Spring的核心技术(二)---容器简介
org.springframework.context.ApplicationContext接口代表了Spring的IoC容器,并且它负责实例化、配置和组装前面提到的Bean对象。这个容器通过 读取配置元数据来获得要实例化、配置和组装的对象的指令。配置元数据被放在XML文件、Java注解或Java代码中,你可以用这些元数据来描述构成应用程序的对象以及这些对象之间的丰富的内部依赖关系。Sprin
org.springframework.context.ApplicationContext接口代表了Spring的IoC容器,并且它负责实例化、配置和组装前面提到的Bean对象。这个容器通过 读取配置元数据来获得要实例化、配置和组装的对象的指令。配置元数据被放在XML文件、Java注解或Java代码中,你可以用这些元数据来描述构成应用程序的对象以及这些对象之间的丰富的内部依赖关系。
Spring提供了几个即装即用的ApplicationContext接口的实现。在独立的应用程序中,通常要创建一个ClassPathXmlApplicationContext类或FileSystemXmlApplicationContext类的实例。虽然可以使用传统的XML格式来定义配置元数据,但是也通过提供一个声明启用其他元数据格式的小的XML配置来指示容器 使用Java注解或代码作为配置元数据。
在大多数应用场景中,用户无需明确的实例化Spring的IoC容器。例如,在一个Web应用场景中,在应用的web.xml文件中通常只需要简单的8行样板化的Web描述符就足够了(详细请看“方便的Web应用程序的ApplicationContext实例化”)。如果使用基于Eclipse的Spring开发套件,只需点几下鼠标或键盘就可以很容易的创建样板配置。
下图是一个Spring如何工作的高级视图。应用程序的类有配置元数据来组合,以便由后续的ApplicationContext接口来创建和初始化,这样就有了一个完全可配置和执行的系统或应用程序。
Spring的IoC容器 |
1. 配置元数据
如上图所示,Spring的IoC容器要使用一种格式的配置元数据,这个配置元数据代表了应用程序的开发者告诉Spring的容器如何实例化、配置和组装应用程序中的对象。
传统的配置元数据是以简单直观的XML格式来提供的,所以本章大都使用这种格式来传达Spring IoC容器的关键概念和功能。
提示:基于XML的元数据不是配置元数据仅有的格式。Spring的IoC容器本身是完全与实际编写的配置元数据的格式解耦的。现在很多开发者都为他们的应用程序选择了基于Java的配置。
关于Spring容器所使用的其他格式的元数据,请看以下内容:
l 基于注解的配置:从Spring2.5开始引入了对基于注解的配置元数据的支持;
l 基于Java的配置:从Spring3.0开始,由Spring的JavaConfig项目所提供的很多功能成为核心Spring框架的一部分。因此通过使用Java而不是XML文件就可以给应用程序的类定义外部的Bean。要使用这些新功能,请看@Configuration、@Bean、@Import、和@DependsOn注解。
Spring的配置包含了至少一个必须由容器来管理的Bean定义。基于XML的配置元数据会把这些Bean的配置作为<bean/>元素放到顶层的<beans/>元素内部。Java配置通常使用@Configuration类中的@Bean注解方法。
这些Bean定义相当于构成应用程序的实际的对象。通常要定义服务层对象、数据访问对象(DAO)、展现层对象(如Struts的Action实例)、基础对象(如Hibernate的SessionFactories)、JMS的Queues等等。通常不会在容器内配置细粒度的域对象,因为这通常是由创建和加载域对象的DAO和业务逻辑来负责的。但是,可以使用Spring跟AspectJ的集成来配置在IoC容器控制之外所创建的配置对象,详细请看“跟Spring一起使用AspectJ来注入依赖域对象”。
下面的示例展示了基于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属性的值指向要合作的对像,这个XML示例没有展示要合作的对象,详细信息请看“依赖”。
2. 实例化一个容器
可以很简单的实例化一个Spring的IoC容器。提供给ApplicationContext构造器的位置路径是实际的资源字符串,它们指向了容器要加载的配置元数据所在的外部资源的位置,如本地文件系统、Java的CLASSPATH等等。
ApplicationContext context =
new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"});
提示:学习了有关Spring的IoC容器之后,就可能想要了解更多有关Spring的Resource的抽象,第7章介绍的“Resources”提供了一种方便的从URI格式的位置定义中读取输入流的机制。实际上,Resource路径被用于构建应用的上下文环境,详细请看“应用程序的上下文环境和资源路径”。
以下是一个展示服务层对象(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>
以下是一个展示数据访问对象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>
在前面的示例中,服务层由类PetStoreServiceImpl和两个数据访问对象JpaAccountDao和JpaItemDao构成(这两个数据访问对象是基于JPA的对象/关系映射标准)。property的name属性指向了JavaBean属性的名字,ref属性指向了另外的Bean定义的名称。id和ref属性之间的关系传递了合作对象之间的依赖。配置对象间依赖的详细信息请看“依赖”。
基于XML的配置元数据的组成
把配置元数据定义到多个XML文件中是有好处的,通常每个独立的XML配置文件代表了架构中的一个逻辑层或模块。
使用应用程序的上下文构造器从这些XML片段中加载Bean的定义。这个构造器需要如前所示多个Resource的位置。一种可选的方法是使用一个或多个<import/>元素从不同的文件中加载Bean的定义,例如:
<beans>
<import resource="services.xml"/>
<import resource="resources/messageSource.xml"/>
<import resource="/resources/themeSource.xml"/>
<bean id="bean1" class="..."/>
<bean id="bean2" class="..."/>
</beans>
在前面的示例中,从services.xml、messageSource.xml和themeSource.xml三个文件中加载外部的Bean定义。所有的位置路径都是相对于入口的定义文件,因此services.xml必须在入口文件相同的目录或类路径中,而messageSource.xml和themeSource.xml必须在入口文件路径下的resources路径中,如上所示,可以忽略前面的斜杠,由于这些路径是相对的,所以比较好的格式是不使用斜杠。被导入的文件的内容,包括顶层的<beans/>元素,必须根据Spring的方案定义的有效的XML的Bean定义。
提示:尽管可以,但是不推荐使用相对的“../”路径来引用父目录中的文件。这样做会要求创建一个依赖当前应用程序之外的文件。实际上,这个引用不推荐使用“classpath:”样式的URL(例如,“classpath:../services.xml”),通常运行时会先选择查看类路径,然后才会查看应用的父目录,因此类路径配置的改变会导致不同的选择,从而选择错误大的目录。
可以始终使用绝对资源路径来代替相对路径,例如“file:C/config/services.xml”或“classpath:/config/services.xml”。但是,要知道把应用程序的配置指定到绝对路径,通常会优先给这些绝对路径保留一个间接的引用,例如通过“${…}”占位符来解决与JVM系统运行时属性的冲突。
3. 使用容器
ApplicationContext是能够保持不同的Bean以及它们的依赖的高级工厂接口。使用T getBean(String name,Class<T> requiredType)方法能够获取相应的Bean的类型。
ApplicationContext能够像下面这样读取和访问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框架为依赖注入提供了诸如控制器和管理JSF Bean的各种Web框架 。
更多推荐
所有评论(0)