- 一、对IOC和DI的基本认识
- (一)理解IoC,即“控制反转”
- (二)IoC能做什么?
- (三)DI又是什么?
- (四)IoC和DI由什么关系呢?
- 二、IOC创建对象的方式
- (一)通过无参构造方法来创建
- (二)通过有参构造方法来创建
- (三)Spring的配置
- 三、依赖注入
- (一)构造器注入
- (二)Set方式注入
- (三)其他扩展方式注入
一、对IOC和DI的基本认识 (一)理解IoC,即“控制反转”
在开发中,Ioc意味着将你设计好的对象交给容器控制,而不是你在你的对象内部直接控制。 要想理解“控制反转”这个词的意思,就要知道,谁控制谁,控制了什么?为什么是反转,哪些地方反转?
- 谁控制了谁,控制了什么?
- 在传统的Java开发中,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建以及外部资源获取。
- 为什么是反转,哪些地方反转?
- 传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象;而反转则是由容器来帮忙创建及注入依赖对象:由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转,依赖对象的获取被反转了。
没有IoC的情况
有了IoC之后的情况
IoC 不是一种技术,只是一种思想,一个重要的面向对象编程的法则, 它能指导我们如何设计出松耦合、更优良的程序。传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是 松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。
其实IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了。
IoC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。
DI—Dependency Injection,即“依赖注入”:组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。 通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。
同样的,理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”
- 谁依赖谁?
- 当然是应用程序依赖于IoC容器
- 为什么需要依赖?
- 应用程序需要IoC容器来提供对象需要的外部资源
- 谁注入谁?
- 很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象
- 注入了什么?
- 就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)
其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以它有个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。
二、IOC创建对象的方式 (一)通过无参构造方法来创建- User.java
public class User { private String name; public User(){ System.out.println("无参构造创建对象!!!"); } public String getName() { return name; } public void setName(String name) { this.name = name; } public void show(){ System.out.println("name="+name); } }
- beans.xml
-->
- 测试类
public class MyTest { public static void main(String[] args) { //Spring容器, ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); User user = (User) context.getBean("user"); user.show(); } }(二)通过有参构造方法来创建
- User.java
public class User { private String name; public User(String name){ //有参构造 this.name=name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void show(){ System.out.println("name="+name); } }
2.beans.xml
- 测试类
public class MyTest { public static void main(String[] args) { //Spring容器, ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); User user = (User) context.getBean("user" ); user.show(); } }(三)Spring的配置
- 可以使用import来导入不同的配置文件,比如在applicationContext.xml中
- 别名
- bean的配置
三、依赖注入 (一)构造器注入
此方法上文已经介绍过了
(二)Set方式注入
- 依赖注入:Set注入
- 依赖:bean对象的创建依赖于容器
- 注入:bean对象中的所有属性,由容器来注入
- Address.java和Student.java
public class Address { private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Address{" + "address='" + address + ''' + '}'; } }
public class Student { private String name; private Address address; private String[] books; private Listhobbies; private Map card; private Set games; private Properties info; private String wife; public String getName() { return name; } public void setName(String name) { this.name = name; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public String[] getBooks() { return books; } public void setBooks(String[] books) { this.books = books; } public List getHobbies() { return hobbies; } public void setHobbies(List hobbies) { this.hobbies = hobbies; } public Map getCard() { return card; } public void setCard(Map card) { this.card = card; } public Set getGames() { return games; } public void setGames(Set games) { this.games = games; } public Properties getInfo() { return info; } public void setInfo(Properties info) { this.info = info; } public String getWife() { return wife; } public void setWife(String wife) { this.wife = wife; } @Override public String toString() { return "Student{" + "name='" + name + ''' + ", address=" + address+ ", books=" + Arrays.toString(books) + ", hobbies=" + hobbies + ", card=" + card + ", games=" + games + ", info=" + info + ", wife='" + wife + ''' + '}'; } }
- beans.xml
- 测试类
public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Student student = (Student) context.getBean("student"); System.out.println(student.getName()); } }
- beans.xml信息补充
(三)其他扩展方式注入红楼梦 水浒传 西游记 三国演义
唱 跳 rap 篮球 LOL CSGO BF5 1910292 男性 xiaomi
此处的其他扩展方式只介绍p命名空间注入二号c命名空间注入
- userbeans.xml
- 测试类
@Test public void test2() { ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml"); User user = (User) context.getBean("user2"); System.out.println(user); }
- 补充:p命名空间和c命名空间不能直接使用,需要导入xml约束!
xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c"
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)