Spring框架对控制反转(Inversion of Control,IoC)进行了实现。
Spring IOC容器管理的对象被称作bean,使用IOC,对象的依赖都是在对象创建时由负责协调系统中各个对象的外部实体提供的。
在Spring中,那些组成你应用程序的主体(backbone)及由Spring IoC容器所管理的对象,被称之为bean。 简单地讲,bean就是由Spring容器初始化、装配及管理的对象,除此之外,bean就与应用程序中的其他对象没有什么区别了。 而bean定义以及bean相互间的依赖关系将通过配置元数据来描述。
org.springframework.beans.factory.BeanFactory 是Spring IoC容器的实际代表者,IoC容器负责容纳此前所描述的bean,并对bean进行管理。
在Spring中,BeanFactory是IoC容器的核心接口。 它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
Spring为我们提供了许多易用的BeanFactory实现, XmlBeanFactory就是最常用的一个。该实现将以XML方式描述组成应用的对象 以及对象间的依赖关系。XmlBeanFactory类将获取此XML配 置元数据,并用它来构建一个完全可配置的系统或应用
Spring IOC的使用减少了对象之间依赖的高度耦合。
上图为Spring中IOC容器的原理图。
在Spring中IOC容器可以通过读取配置的元数据来对各个对象(Bean)进行实例化、配置以及装载,而通常在Spring中是使用XML文档来描述元数据的。
在IoC容器中至少都会有一个Bean描述,但往往会有多个Bean的描述,而Bean的定义也非常广泛,包括业务层,服务对象,表示层对象等。
以下为一个基于XML的配置元数据的基本结构(即Spring体验中的applicationContext.xml文件):
<?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,Class类全名等属性,在标签中还会有property等子标签均与该bean相关(需要根据bean来设置)--> <bean id="..." class="..."> </bean> <bean id="..." class="..."> </bean> </beans>
例如:
<bean id="greetingServiceImpl" class="cn.csdn.service.GreetingServiceImpl"> <property name="say"> <value>你好!</value> </property> </bean>
对应的Bean的GreetingServiceImpl:
package cn.csdn.service; public class GreetingServiceImpl implements GreetingService { /**私有属性*/ private String say; @Override public void say() { System.out.println("你打的招呼是:"+say); } public void setSay(String say){ this.say=say; }
该类继承的接口GreetingService:
package cn.csdn.service; public interface GreetingService { void say(); }
那么何为Spring的IoC控制反转呢?
我们来创建一个JUnit测试类:
package cn.csdn.junit; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; import cn.csdn.service.GreetingService; public class GreetingTest { /**测试GreetingServiceImpl的方法*/ @Test public void test1(){ /**加载spring容器 可以解析多个配置文件 采用数组的方式传递*/ ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"}); /**IOC的控制反转体现*/ GreetingService greetingService = (GreetingService) ac.getBean("greetingServiceImpl"); greetingService.say(); } }
在测试类中我们看到想要实现IoC的控制反转,首先应该加在容器:
加在容器的写法有以下几种:
① 、可以同时配置多个XML描述文件
ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});
② 、只能描述当前项目路径下的一个XML描述文件
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
③ 、使用匹配的方法在路径下寻找符合条件的XML描述文件
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:app*.xml");
然后,我们需要通过IoC的反转机制获得Bean的对象:
GreetingService greetingService = (GreetingService) ac.getBean("greetingServiceImpl");
最后,我们通过获得Bean对象调用Bean中的方法,输出如下:
打的招呼是:你好!
请注意:因为刚使用ITEYE博客,对其FCK的排版使用不是很熟悉,所以请大家复制代码的时候把其中的HTML<span></span>标签去掉,在这里大家见谅。