IOC(Inversion of Control)控制反转。
初识其义
在开发过程了,我们要尽量的降低程序之间的耦合性,便于后期的维护和程序的健壮性。Spring Ioc(控制反转)较大程度上的帮我们解决了程序之间的耦合性问题。举个例子,我们在使用一个对象的方法或属性的时候,常规的我们都是new 一个对象,通过这个对象来获取其对应的方法和属性,我们之间测试代码时,这样当然没有问题,当面对一个大型的工程时,我们采取这样的方法,会产生许多new出来的对象,这样不仅增加了程序之间的耦合性,也不利于后期代码的维护和升级。写时一时爽,哭死一片人,尤其是后面维护的人和升级的人。最近这写一个需求,深有体会啊。
Spring框架很好的帮我们解决了这个问题,不需要我们new一个对象,而是由Spring容器来创建,Spring容器会控制程序之间的关系,而不是由调用者管理。控制权由刚开始我们创建到Spring容器控制,控制权发生反转。
控制反转实际上是由SpringIoc容器管理。那么接下来,我们来看看Spring IOC容器
幕后真凶
Spring Ioc 主要基于BeanFactory 和ApplicationContext 两个接口。
1.BeanFactory由org.springframework.beans.factory.BeanFactory接口定义,提供完整的Ioc服务支持,是由一个管理Bean的工厂,主要负责初始化各种Bean。
其实现类有许多,比较常用的是org.springframework.beans.factory.xml.XmlBeanFactory,该类会根据XML配置文件中的定义来装配Bean。
使用该类时,读取xml配置文件时,需要提供绝对路径来。example:
BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource("D:\test\*.xml")); //*.xml文件必须提供绝对路径,相对路径不行
Test test = (Test)beanFactory.getBean("test"); // 获取Test类的对象
实际项目中很少使用。
2.ApplicationContext是BeanFactory的子接口,也称为应用上下文。其有org.springcontext.ApplicationContext接口定义。
其接口的功能包含BeanFactory的所有功能(它是BeanFactory子接口),还拓展了对国际化、资源访问、事件传播等内容的支持。
创建ApplicationContext接口实例一般有一下三种方法:
a. ClassPathXmlApplicationContext创建 ,从其中的名字我们可以看出,其读取*.xml文件的方法是从类路径即src根目录读取。
b. FileSystemXmlApplicationContext创建 ,从指定文件的绝对路径中寻找Xml文件,找到并装载完成ApplicationContext实例化工作。
c. 通过web服务器实例化ApplicationContext容器, web服务器实例化时,一般基于org.springframework.web.context.ContextLoaderListener的实现方式。
在web.xml中配置:
<!--实例化ApplicationContext容器-->
<context-param>
<!--加载applicationContext容器-->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--指定以ContextLoaderListener方式启动Spring容器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Dependency Injection (依赖注入)
依赖注入的作用是在使用Spring框架创建对象时动态地将其所依赖的对象(如属性值)注入到Bean组建中去。
依赖注入一般有两种方法注入
1.构造方法注入:
public interface TestService {....}
public class TestServiceImpl implements TestService{
private B b ;
public A (B b){
this.b = b ;
}
....
}
配置文件 关键代码:
<bean id = "b" class = "B类的权限定名">
<bean id = "testService" class="实现TestService接口的类的全限定名"》
<!--将B类 注入到 TestServiceImpl 属性 b上 -->
<constructor-arg index="0" ref = "b" />
</bean>
说明: index用于定义参数的位置,如果参数是常量值,ref 由value 代替。
2.setter方法注入:
public interface TestService {....}
public class TestServiceImpl implements TestService{
private B bname ;
public void setB (B bname){
this.bname = bname ;
}
....
}
<bean id = "bname" class = "B类的权限定名">
<bean id = "testService" class="实现TestService接口的类的全限定名TestServiceImpl"》
<!--将B类 注入到 TestServiceImpl 属性 b上 -->
<property name="b" ref = "bname" />
</bean>
TestServiceImpl类托管给Spring ,SPring创造其对象的同时,调用setter方法完成依赖注入。