Spring IOC之容器概述
1.SpringIOC容器和beans介绍
IOC的依赖注入是这样的,对象定义他们的依赖也就是他们需要在一起起作用的对象是通过构造器参数以及工厂方法的参数或者是当他们被构建或者是从工厂中返回时设置在对象实例中的属性。但它创建bean的时候容器就会注入这些依赖。这个过程实现了反转,命名为控制反转(Ioc)的原因是它通过直接的构造类或者例如服务定位模式的机制来控制实例化或者依赖的位置。
org.springframework.beans和org.springframework.context包是Spring框架IOC容器 基础。 BeanFactory接口提供了一个高级配置机制来管理任何类型的对象。 ApplicationContext是BeanFactory的子接口。它加入了更简单的功能整和:Spring AOP功能,消息资源处理(用于国际化),事件发布,可以在web应用中的使用的应用层上下文比如WebApplicationContext。
简而言之,BeanFactory提供注册和基础功能,而且ApplicationContext 增加了更多的企业级功能。ApplicationContext是BeanFactory的超集。
2.ApplicationContext
org.springframework.context.ApplicationContext接口表示IOC容器,它用于实例化配置组装前面提到的beans.容器通过读取配置元数据信息来得到它关于对象实例化配置以及组装的指令信息。配置的元数据信息可以是XML文件、Java注解、或者是Java代码。它允许你去表示构成你的程序的对象以及这些对象之间的依赖性。
ApplicationContext接口的几个实现可以在Spring中直接使用。在单独的引用中它通常去创建一个ClassPathXmlApplicationContext或者是FileSystemXmlApplicationContext实例。尽快可以通过XML格式来定义配置元数据信息,你也可以通过为另外的元数据格式提供支持的一小段的XML配置来使用Java注解或者代码去给告知容器信息。
在绝大部分场景中,显示的用户代码中不需要再一个Spring IOC容器来实例化一个或者是多个实例。例如,在一个Web应用场景中,一个简单的大约八行的样板文件web.xml就可以满足需要。如果你使用基于Eclipse的SpringSource Tool Suite的开发环境,这个样板配置文件很容易通过几个鼠标或者键盘的敲击来完成。
下面的通过一个高阶视图展示了Spring是如何工作的。你的程序类是通过配置数据联合在一块的以便ApplicationContext被创建和初始化后,你就会有一个充分的可配置运行的系统或者是应用程序。
3.配置数据
正如上面图形展示的那样,Spring IOC容器需要一种形式的配置数据,这个配置数据表示你作为一个应用开发者去告诉Spring IOC容器去实例化、配置和组装在你程序中的对象。
配置元数据习惯上使用XML格式来配置。基于XML格式的配置并不仅仅是唯一的配置方式。开发者也会选择使用java注解的配置方式。
- Annotation-based configuration:在Spring2.5中引入了注解配置方式。
- Java-based configuration:从Spring3.0开始,很多通过 Spring JavaConfig项目提供的功能成为了spring框架核心的一部分。所以你可以在定义bean通过使用Java而不仅是XML文件。为了使用这些新的功能。可以留意下@Configuration, @Bean, @Import and @DependsOn 注解。
Spring配置中一般至少会有一个通常会有多个由容器来管理的bean的定义。基于XML配置的元数据中可以看到定义在
这些配置在你的实际项目中可以选择。一般来说你定义Service层对象、DAOs对象、像Struts Action的表示层对象、比如Hibernate SessionFactories的持久层对象、JMS队列等等。一般来说我们不在容易中配置模型对象,以为它一般是由DAO和业务逻辑来创建和加载的。但是,你可以使用 AspectJ 来配置这些对象,这个是springIOC容器的外面的。
下面就是基于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.xsd">
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here -->
</beans>
id
属性你用来标识单独的bean定义的字符串。class
属性定义了bean的类型,使用了完整的类名。id属性的值用来指明对应的对象。
4.实例化一个容器
实例化一个Spring IOC容器是简单的。传递给ApplicationContext 构造器的路径是资源字符串,它允许容器去加载包括文件系统或者是CLASSPATH路径的不同来源的配置数据。
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] { "services.xml", "daos.xml"});
下面是Service层对象的配置信息(services.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.xsd">
<!-- services -->
<bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
<property name="accountDao" ref="accountDao"/>
<property name="itemDao" ref="itemDao"/>
<!-- additional collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions for services go here -->
</beans
下面是数据访问层的的对象s daos.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.xsd">
<bean id="accountDao"
class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao">
<!-- additional collaborators and configuration for this bean go here -->
</bean>
<bean id="itemDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao">
<!-- additional collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions for data access objects go here -->
</beans>
在前面的例子中,Service层由PetStoreServiceImpl还有两个DAO层的JpaAccountDao 、 JpaItemDao组成。 property name指明了JavaBean的属性,ref元素执行了其他的bean定义的名字。通过id 和ref的联系表明了两个关联对象的依赖。
5.基于XML的配置信息
在多个XML文件中定义bean是很有用的。而每个单独的配置文件表示你的架构中一个逻辑层或者模块。你可以使用应用程序上下文构造器从这些文件片段中加载bean的定义。这个构造器可以还有多个Resource位置参数。我们可以使用一个或者多个
beans>
<import resource="services.xml"/>
<import resource="resources/messageSource.xml"/>
<import resource="/resources/themeSource.xml"/>
<bean id="bean1" class="..."/>
<bean id="bean2" class="..."/>
</beans>
在上面的例子中,外部的bean定义是通过三个文件来加载的:services.xml,
messageSource.xml,和themeSource.xml.。在被引入的时候这些位置路径都是相对于
定义文件的。所以services.xml必须要在相同的目录或者是classpath位置中在引入的时候。
而messageSource.xml and themeSource.xm必须要在resources文件夹下面。
6.使用容器
ApplicationContext是用来管理注册的不同bean以及他们依赖的高级工程接口。使用方法T getBean(String name, Class
requiredType) 你可以捡出自己bean的实例。 ApplicationContex是你读取bean的定义并且向下面这样访问他们。
// create and configure beans
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] { "services.xml", "daos.xml"});
// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService. class);
// use configured instance
List<String> userList = service.getUsernameList();
你可以使用getBean()来获取你的bean实例。ApplicationContext接口有几个检出bean的方法,但是不信的是你的应用程序代码应该永远都不要使用他们。实际上,你的应用程序中不应该调用getBean()方法,一点也不要依赖Spring API。例如,Spring整合了web框架提供了针对不同的web框架类像控制器JSF管理bean的 依赖注入。