1、IOC本质
对象之间耦合度过高的系统,必然会出现牵一发而动全身的情形。为了解决对象之间的耦合度过高的问题,软件专家Michael Mattson提出了IOC理论,用来实现对象之间的“解耦”
2、控制反转(IoC)
由于引进了中间位置的“第三方”,也就是IOC容器,使得A、B、C、D这4个对象没有了耦合关系,齿轮之间的传动全部依靠“第三方”了,全部对象的控制权全部上缴给“第三方”IOC容器,
个人认为所谓控制反转就是:获得依赖对象的方式反转了,控制权颠倒过来了,由主动行为变为了被动行为。
3、IOC的别名:依赖注入(DI)
控制被反转之后,获得依赖对象的过程由自身管理变为了由IOC容器主动注入。于是,“控制反转”取了一个更合适的名字叫做“依赖注入(Dependency Injection)”。所谓依赖注入,就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象之中。
4、依赖注入的方式:
(1.1) xml配置之Setter 注入
我创建了一个pojo类User,它由两个属性 name和age,然后定义了他们的get 和set方法。
然后在xml文件中去配置bean
<?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-2.5.xsd">
<bean id="user" class="com.dbf.pojo.User">
<property name="name" value="dbf"/>
<property name="age" value="18"/>
</bean>
</beans>
最后从IOC容器里面取出来
//获取spring上下文
ApplicationContext applicationContext=new ClassPathXmlApplicationContext("application.xml");
User user=(User) applicationContext.getBean("user");
(1.2) xml配置之构造器注入
还是用上面的例子,我在User类里面定义了有参和无参构造器,然后在xml文件中配置,从IOC容器里也是一样的取
<bean id="user" class="com.dbf.pojo.User">
<constructor-arg name="name" value="dbf"/>
<constructor-arg name="age" value="18"/>
</bean>
这个使用的比较少,因为他必须要有带参的构造,而且必须传入所有需要的参数,没有setter注入灵活
(1.3) xml配置之接口注入
已经被官方给去掉了,不去了解了
(2)自动装配
可以在beans头文件中开启,也可以在bean中开启
<?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-2.5.xsd"
default-autowire="byType">
<bean id="user" class="com.dbf.pojo.User" autowire="byType"></bean>
</beans>
- no:不进行自动装配,手动设置 Bean 的依赖关系。
- byName:根据 Bean 的名字进行自动装配。根据set方法的名字
- byType:根据 Bean 的类型进行自动装配。
- constructor:类似于 byType,不过是应用于构造器的参数,如果正好有一个 Bean 与构造器的参数类型相同则可以自动装配,否则会导致错误。
- autodetect:如果有默认的构造器,则通过 constructor 的方式进行自动装配,否则使用 byType的方式进行自动装配。
(3)注解配置
在代码中加入@Resource或者@Autowired
-
@Autowired是由Spring提供;@Resource是由J2EE提供,需要JDK1.6及以上。
-
@Autowired只按照类型注入;@Resource默认按名称自动注入,也提供按照类型注入;
-
@Autowired按类型装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它required属性为false。如果我们想使用按名称装配,可以结合@Qualifier注解一起使用。
-
@Resource装配顺序
1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;
4、IOC的好处
-
可维护性比较好,非常便于进行单元测试,便于调试程序和诊断故障
-
每个开发团队的成员都只需要关心实现自身的业务逻辑,完全不用去关心其它的人工作进展
-
提高了模块的可复用性
-
更换一个实现子类将会变得很简单,只要修改配置文件就可以了,完全具有热插拨的特性
5、缺点
- 生成对象的步骤变得有些复杂,本来是两者之间的事情,又凭空多出一道手续,所以,我们在刚开始使用IOC框架的时候,会感觉系统变得不太直观
- 由于IOC容器生成对象是通过反射方式,在运行效率上有一定的损耗
- 需要进行大量的配制工作,比较繁琐