参考文章:http://blog.csdn.net/m13666368773/article/details/7802126
先看上面这篇文章!
目的:松耦合、松耦合、松耦合
原理:Don't call us, we'll call you(别找我们,我们会来找你的)。
所有的组件都是被动的,所有的组件初始化和调用都有容器负责。组件处在一个容器当中,由容器负责管理。简单来说,就是由容器控制程序之间的关系,而非传统实现中,由程序代码直接操控,即在一个类中调用另外一个类。
控制权由应用代码中转到了外部容器,控制权的转移,即所谓反转。
IOC的主要组件:
1、Beans
Beans是指项目中提供业务功能的Bean,即容器要管理的Bean。
2、配置文件(applicationContext.xml)
Spring中对Bean的管理是在配置文件中进行的。告诉容器需要哪些Bean,以及容器是如何使用IoC将它们配置起来
3、BeanFactory接口及其相关类
BeanFactory采用了工厂设计模式,即Bean容器模式,负责读取Bean的配置文件,管理对象的生成、加载、维护Bean对象之间的依赖关系,负责Bean对象的生命周期。
BeanFactory factory = XmlBeanFactory( new FileInputStream("applicationContext.xml"));
BeanFactory的常用方法如下:
(1)getBean(String name):根据Bean的id生成该Bean的对象。
(2)getBean(String name, Class requiredType):根据Bean的id和相应类生成该Bean的对象。
4、ApplicationContext接口及其相关类
(1)FileSystemXmlApplicationContext:从文件系统中的XML文件加载上下文中定义的信息
(2)ClassPathXmlApplicationContext:从类路径中的XML文件加载上下文中定义的信息
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
(3)XmlWebApplicationContext:从Web系统中的XML文件加载上下文中定义的信息
注入的两种方式
1、setter注入
项目有Person接口和Language接口
package iocexample2;public interface Person {void speak(); }
package iocexample2;public interface Language {String kind(); }
两个接口的实现类分别为Chinese类和English类,在Chinese类中要用到Language对象
package iocexample2; /** 没有实例化Language,在IOC容器中设置了依赖关系*/public class Chinese implements Person {private Language language;public void speak(){System.out.println(language.kind());}//setter注入public void setLanguage(Language language) {this.language = language;}}
package iocexample2;public class English implements Language{public String kind(){return "中国人喜欢说汉语,也会说英语!";} }
因Language是接口,所以用其实现类来创建对象,在Chinese类中为其写一个setter方法,即 setLanguage;通过Spring的配置文件来完成对象的注入,配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 配置bean id:标识容器中的bean,id唯一class:bean的全类名,通过反射的方式在IOC容器中创建Bean,所以要求Bean中必须有无参构造器property的name是属性,value是给属性的赋值--><!-- 1、setter注入 --><bean id="中国人" class="iocexample2.Chinese"><property name="language" ref="英语"></property></bean><!-- 注入English --><bean id="英语" class="iocexample2.English"></bean></beans>
测试该项目的main类如下:
package iocexample2;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class main {public static void main(String[] args) {ApplicationContext ac= new ClassPathXmlApplicationContext("applicationContext.xml");Person person= (Person) ac.getBean("中国人");person.speak();}}
2、构造注入
只需修改Chinese类和配置文件,如下:
package iocexample2; /** 没有实例化Language,在IOC容器中设置了依赖关系*/public class Chinese implements Person {private Language language;public void speak(){System.out.println(language.kind());}//构造注入public Chinese(){}public Chinese(Language language){this.language = language;} }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 配置bean id:标识容器中的bean,id唯一class:bean的全类名,通过反射的方式在IOC容器中创建Bean,所以要求Bean中必须有无参构造器property的name是属性,value是给属性的赋值--><!-- 2、构造器注入 --><bean id="中国人" class="iocexample2.Chinese"><constructor-arg ref="英语"></constructor-arg></bean><!-- 注入English --><bean id="英语" class="iocexample2.English"></bean></beans>
两种方式的运行结果一样,区别在于:
setter注入:先创建一个默认的Bean实例,然后调用对应的setter方法注入依赖关系
构造注入:创建Bean实例时,已经完成了依赖关系的注入