Core Technologies

更新于三月三十一号 21:01html

原文

This part of the reference documentation covers all the technologies that are absolutely integral to the Spring Framework.java

Foremost amongst these is the Spring Framework’s Inversion of Control (IoC) container. A thorough treatment of the Spring Framework’s IoC container is closely followed by comprehensive coverage of Spring’s Aspect-Oriented Programming (AOP) technologies. The Spring Framework has its own AOP framework, which is conceptually easy to understand and which successfully addresses the 80% sweet spot of AOP requirements in Java enterprise programming.ios

Coverage of Spring’s integration with AspectJ (currently the richest — in terms of features - and certainly most mature AOP implementation in the Java enterprise space) is also provided.程序员

1. The IoC Container

This chapter covers Spring’s Inversion of Control (IoC) container.web

1.1. Introduction to the Spring IoC Container and Beans

This chapter covers the Spring Framework implementation of the Inversion of Control (IoC) principle. IoC is also known as dependency injection (DI). It is a process whereby objects define their dependencies (that is, the other objects they work with) only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method. The container then injects those dependencies when it creates the bean. This process is fundamentally the inverse (hence the name, Inversion of Control) of the bean itself controlling the instantiation or location of its dependencies by using direct construction of classes or a mechanism such as the Service Locator pattern.spring

The org.springframework.beans and org.springframework.context packages are the basis for Spring Framework’s IoC container. The BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object. ApplicationContext is a sub-interface of BeanFactory. It adds:express

  • Easier integration with Spring’s AOP features
  • Message resource handling (for use in internationalization)
  • Event publication
  • Application-layer specific contexts such as the WebApplicationContext for use in web applications.

In short, the BeanFactory provides the configuration framework and basic functionality, and the ApplicationContext adds more enterprise-specific functionality. The ApplicationContext is a complete superset of the BeanFactory and is used exclusively in this chapter in descriptions of Spring’s IoC container. For more information on using the BeanFactory instead of the ApplicationContext, see The BeanFactory.bash

In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC container are called beans. A bean is an object that is instantiated, assembled, and otherwise managed by a Spring IoC container. Otherwise, a bean is simply one of many objects in your application. Beans, and the dependencies among them, are reflected in the configuration metadata used by a container.架构

1.2. Container Overview

The org.springframework.context.ApplicationContext interface represents the Spring IoC container and is responsible for instantiating, configuring, and assembling the beans. The container gets its instructions on what objects to instantiate, configure, and assemble by reading configuration metadata. The configuration metadata is represented in XML, Java annotations, or Java code. It lets you express the objects that compose your application and the rich interdependencies between those objects.app

Several implementations of the ApplicationContext interface are supplied with Spring. In stand-alone applications, it is common to create an instance of ClassPathXmlApplicationContext or FileSystemXmlApplicationContext. While XML has been the traditional format for defining configuration metadata, you can instruct the container to use Java annotations or code as the metadata format by providing a small amount of XML configuration to declaratively enable support for these additional metadata formats.

In most application scenarios, explicit user code is not required to instantiate one or more instances of a Spring IoC container. For example, in a web application scenario, a simple eight (or so) lines of boilerplate web descriptor XML in the web.xml file of the application typically suffices (see Convenient ApplicationContext Instantiation for Web Applications). If you use the Spring Tool Suite (an Eclipse-powered development environment), you can easily create this boilerplate configuration with a few mouse clicks or keystrokes.

The following diagram shows a high-level view of how Spring works. Your application classes are combined with configuration metadata so that, after the ApplicationContext is created and initialized, you have a fully configured and executable system or application.

Spring IoC container

1.2.1 Configuration Metadata

As the preceding diagram shows, the Spring IoC container consumes a form of configuration metadata. This configuration metadata represents how you, as an application developer, tell the Spring container to instantiate, configure, and assemble the objects in your application.

Configuration metadata is traditionally supplied in a simple and intuitive XML format, which is what most of this chapter uses to convey key concepts and features of the Spring IoC container.

XML-based metadata is not the only allowed form of configuration metadata. The Spring IoC container itself is totally decoupled from the format in which this configuration metadata is actually written. These days, many developers choose Java-based configuration for their Spring applications.

For information about using other forms of metadata with the Spring container, see:

  • Annotation-based configuration: Spring 2.5 introduced support for annotation-based configuration metadata.
  • Java-based configuration: Starting with Spring 3.0, many features provided by the Spring JavaConfig project became part of the core Spring Framework. Thus, you can define beans external to your application classes by using Java rather than XML files. To use these new features, see the @Configuration, @Bean, @Import, and @DependsOn annotations.

Spring configuration consists of at least one and typically more than one bean definition that the container must manage. XML-based configuration metadata configures these beans as <bean/> elements inside a top-level <beans/> element. Java configuration typically uses @Bean-annotated methods within a @Configuration class.

These bean definitions correspond to the actual objects that make up your application. Typically, you define service layer objects, data access objects (DAOs), presentation objects such as Struts Action instances, infrastructure objects such as Hibernate SessionFactories, JMS Queues, and so forth. Typically, one does not configure fine-grained domain objects in the container, because it is usually the responsibility of DAOs and business logic to create and load domain objects. However, you can use Spring’s integration with AspectJ to configure objects that have been created outside the control of an IoC container. See Using AspectJ to dependency-inject domain objects with Spring.

The following example shows the basic structure of XML-based configuration metadata:

<?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="...">   (1)(2)
        <!-- 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>
(1) The id attribute is a string that identifies the individual bean definition.
(2) The class attribute defines the type of the bean and uses the fully qualified classname.
复制代码

The value of the id attribute refers to collaborating objects. The XML for referring to collaborating objects is not shown in this example. See Dependencies for more information.

1.2.2 Instantiating a Container

The location path or paths supplied to an ApplicationContext constructor are resource strings that let the container load configuration metadata from a variety of external resources, such as the local file system, the Java CLASSPATH, and so on.

ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
复制代码

After you learn about Spring’s IoC container, you may want to know more about Spring’s Resource abstraction (as described in Resources), which provides a convenient mechanism for reading an InputStream from locations defined in a URI syntax. In particular, Resource paths are used to construct applications contexts, as described in Application Contexts and Resource Paths.

The following example shows the service layer objects (services.xml) configuration file:

<?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>
复制代码

The following example shows the data access objects daos.xml file:

<?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>
复制代码

In the preceding example, the service layer consists of the PetStoreServiceImpl class and two data access objects of the types JpaAccountDao and JpaItemDao (based on the JPA Object-Relational Mapping standard). The property name element refers to the name of the JavaBean property, and the ref element refers to the name of another bean definition. This linkage between id and ref elements expresses the dependency between collaborating objects. For details of configuring an object’s dependencies, see Dependencies.

Composing XML-based Configuration Metadata

It can be useful to have bean definitions span multiple XML files. Often, each individual XML configuration file represents a logical layer or module in your architecture.

You can use the application context constructor to load bean definitions from all these XML fragments. This constructor takes multiple Resource locations, as was shown in the previous section. Alternatively, use one or more occurrences of the <import/> element to load bean definitions from another file or files. The following example shows how to do so:

<beans>
    <import resource="services.xml"/>
    <import resource="resources/messageSource.xml"/>
    <import resource="/resources/themeSource.xml"/>

    <bean id="bean1" class="..."/>
    <bean id="bean2" class="..."/>
</beans>
复制代码

In the preceding example, external bean definitions are loaded from three files: services.xml, messageSource.xml, and themeSource.xml. All location paths are relative to the definition file doing the importing, so services.xml must be in the same directory or classpath location as the file doing the importing, while messageSource.xml and themeSource.xml must be in a resources location below the location of the importing file. As you can see, a leading slash is ignored. However, given that these paths are relative, it is better form not to use the slash at all. The contents of the files being imported, including the top level <beans/> element, must be valid XML bean definitions, according to the Spring Schema.

It is possible, but not recommended, to reference files in parent directories using a relative "../" path. Doing so creates a dependency on a file that is outside the current application. In particular, this reference is not recommended for classpath: URLs (for example, classpath:../services.xml), where the runtime resolution process chooses the “nearest” classpath root and then looks into its parent directory. Classpath configuration changes may lead to the choice of a different, incorrect directory. You can always use fully qualified resource locations instead of relative paths: for example, file:C:/config/services.xml or classpath:/config/services.xml. However, be aware that you are coupling your application’s configuration to specific absolute locations. It is generally preferable to keep an indirection for such absolute locations — for example, through "${…​}" placeholders that are resolved against JVM system properties at runtime.

The namespace itself provices the import directive feature. Further configuration features beyond plain bean definitions are available in a selection of XML namespaces provided by Spring — for example, the context and util namespaces.

1.2.3. Using the Container

The ApplicationContext is the interface for an advanced factory capable of maintaining a registry of different beans and their dependencies. By using the method T getBean(String name, Class<T> requiredType), you can retrieve instances of your beans.

The ApplicationContext lets you read bean definitions and access them, as the following example shows:

// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService.class);

// use configured instance
List<String> userList = service.getUsernameList();
复制代码

The most flexible variant is GenericApplicationContext in combination with reader delegates — for example, with XmlBeanDefinitionReader for XML files, as the following example shows:

GenericApplicationContext context = new GenericApplicationContext();
new XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml");
context.refresh();
复制代码

You can mix and match such reader delegates on the same ApplicationContext, reading bean definitions from diverse configuration sources.

You can then use getBean to retrieve instances of your beans. The ApplicationContext interface has a few other methods for retrieving beans, but, ideally, your application code should never use them. Indeed, your application code should have no calls to the getBean() method at all and thus have no dependency on Spring APIs at all. For example, Spring’s integration with web frameworks provides dependency injection for various web framework components such as controllers and JSF-managed beans, letting you declare a dependency on a specific bean through metadata (such as an autowiring annotation).

翻译

这部分参考文档涵盖绝大部分 Spring 框架使用的技术。

最重要的是 Spring 框架的 IoC 容器,与它关系密切的是 Spring AOP 技术。Spring 有它本身易于理解的 AOP 框架,并成功解决了 80% 在 Java 企业开发中对 AOP 的要求。

Spring 也能集成 AspectJ(当前拥有最多特性,在 Java 企业开发领域最成熟的 AOP 实现)。

1. IoC 容器

这一章讲述 Spring IoC 容器。

1.1 介绍 Spring IoC 容器和 Beans

这一章包含 Spring 框架实现控制反转(IoC)的原理。IoC 也被称为依赖注入(Dependency Injection)。经过对象定义它的依赖,仅能经过构造器参数、工厂方法的参数,在那些在对象初始化以后的属性或者工厂方法返回结果。容器在建立 Bean 时,再将它依赖的 Bean 注入。这个过程与 Bean 控制依赖属性的实例化,或经过类构造器或如像 Service Locator 这样的机制相比是彻底相反的(所以叫作控制反转)。

org.springframework.beansorg.springframework.context 包是 Spring IoC 容器的基础。BeanFactory 接口提供了一个管理任何类型对象的机制。ApplicationContextBeanFactory 的子接口,它添加了以下特性:

  • 更易于集成 Spring AOP
  • 消息资源处理(用于国际化)
  • 事件发布
  • 应用级别的容器,如在 Web 应用中使用的 WebApplicationContext

简而言之,BeanFactory 提供了配置和基本功能,ApplicationContext 则添加了更多企业开发的功能。ApplicationContextBeanFactory 的超集,它仅仅在本章 Spring IoC 容器中有描述。

在 Spring 框架中,应用中建立并被 Spring IoC 容器管理的对象称为「Bean」。Bean 的初始化、装配等被 Spring IoC 容器管理。Beans 以及他们的依赖项,映射为配置元数据被 Spring 使用。

1.2 容器概览

ApplicationContext 接口表明 Spring IoC 容器,负责 Bean 的实例化、配置以及组装工做。Spring 容器经过读取配置元信息来获取对象实例化、配置以及组装的说明。配置元信息以 XML、注解或者配置类的形式存在。配置元信息用来表述那些构成你应用的对象,以及对象之间的相互依赖关系。

Spring 提供了 ApplicationContext 接口的一些实现。在应用中,常常建立 ClassPathXmlApplicationContext 或者 FileSystemXmlApplicationContext。虽然 XML 是定义配置元数据的传统方式,你仍旧能够用 Java 注解或者代码来指示容器,只须要在 XML 配置中声明支持这些额外数据源格式。

在大多数状况下,不须要为容器中的 Bean 对象做出明确编码。好比在 Web 应用的 web.xml 中,大概八行样板代码就足够了。你也可使用 Spring Tool Suite,经过鼠标单击和键盘操做来建立样板配置。

下图粗略的展现了 Spring 是如何工做的。你的应用类和配置元信息绑定在一块儿,所以在 ApplicationContext 建立和初始化后,你会获得一个彻底配置好的且能执行的应用。

Spring IoC container

1.2.1 配置元数据

如上图所示,Spring IoC 容器消费着由配置元数据组成的表格。配置元数据表明着你做为应用开发者,告知 Spring 容器来初始化、配置以及组装应用中的对象。

传统上,配置元数据以简单直观的 XML 格式提供。本章大部份内容用于传达 Spring IoC 容器的核心概念和特性。

XML 格式不是配置元信息的惟一格式,Spring IoC 容器与元信息的配置格式彻底解耦。最近不少程序员选择基于 Java 的配置格式。

使用 Spring 容器的其余元信息格式,如:

  • 基于注解的配置:Spring 从 2.5 开始支持基于注解的配置元信息
  • 基于 Java 代码的配置:从 3.0 开始,许多由 Java 代码配置项目提供的特性开始成为 Spring 框架的核心。所以,您能够在项目中使用 Java 代码代替 XML 文件来定义 beans。请使用 @Configuration@Bean@Import 以及 @DependsOn 注解来应用这些特性。

Spring 配置文件包含至少一个(一般是多个)Bean 定义。基于 XML 的配置元文件,在外层 <beans/> 标签内的 <bean/> 标签中定义单个 Bean。Java 配置一般在 @Configuration 标记的类中,定义 @Bean 注解的方法。

这些 Bean 定义对应着您应用中的实际对象。一般状况,您会定义服务层对象(Service)、数据访问对象(data access objects)、展现层(如 Struts)实例、基础设施对象(如 Hibernate SessionFactories, JMS Queues 等)。一般不须要在容器中建立细粒度的领域对象,由于这由 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="..." class="...">  (1)(2)
        <!-- 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>
(1) String 类型的 id 属性,是定义 bean 的标识
(2) class 属性使用全类名定义 bean 的类型
复制代码

属性 id 关联着相应的对象。实例中给出的并不完整,在 Dependencies 章节查看详细内容。

初始化一个容器

ApplicationContext 构造器中提供的本地路径或者多个路径(如本地文件系统,Java CLASSPATH),指导容器从外部配置中加载配置元信息。

ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
复制代码

在你学习 Spring IoC 容器后,你可能想深刻了解 Spring 抽象的 Resource,它提供了方便的机制从 URI 格式定义的 InputStream 流中读取信息。尤为是,Resource 路径被用来构造应用上下文,在 Application Contexts and Resource Paths 中有描述。

下面的例子展现了服务层(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>
复制代码

下面的例子展现了数据访问层 dao.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 类以及两个数据访问对象 JpaAccountDaoJpaItemDao(基于对象关系映射 JPA)。name 元素为当前 Java Bean 的属性名,ref 元素关联着另外一个 Bean 定义的名称。idref 元素的联系表现了关联对象的依赖关系。请在 Dependencies 章节查看对象依赖的详细内容。

组成 XML 配置元数据

在多个 XML 文件中定义 bean 是颇有用的。一般每一个单独的 XML 文件配置文件,表明着您架构中的某个逻辑层次或模块。

你可使用应用上下文构造器来加载多个 XML 配置文件。正如前文所述,这个构造器使用多个 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 必定和当前文件在相同目录或者 classpath,然而 messageSource.xml themeSource.xml 必定在当前文件的下级目录。**正如你看到的,第一个 / 是被忽略的。**既然这些路径都是相对的,最好就不用第一个 /。被导入的文件内容,包括最顶级的 <beans> 元素,但必须符合 Spring Schema 格式。

能够用 "../" 相对路径来关联父目录中的文件,但不建议这么作。这样作的话,会使当前应用依赖外部的文件。这种引用尤为不建议在 classpath 中使用:URLs(如 classpath:../services.xml)运行时 进程会选择最近的 classpath 根目录,而后在它的父目录中寻找。classpath 配置修改可能会致使选择错误的目录。 您也可使用绝对路径,如:file:C:/config/services.xml 或者 classpath:/config/services.xml。可是,请注意你正在将您应用程序的配置文件和绝对路径绑定在一块儿。一般状况下,最好是为这样的绝对路径有一个间接关联,好比,经过 ${xxx} 替代符在运行时解析 JVM 参数。

命名空间自己提供了 import 指令。Spring 提供了除普通 bean 定义以外的其余 XML 命名空间特性,如 contextutil,也可使用。

1.2.3 使用容器

ApplicationContext 接口提供了获取各类 Bean 以及它们依赖的能力。经过调用 T getBean(String name, Class<T> requiredType) 方法,能够获得 bean 的实例。

ApplicationContext 能够用来读 bean 定义而后获取他们,以下所示:

// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService.class);

// use configured instance
List<String> userList = service.getUsernameList();
复制代码

最灵活的变体是 GenericApplicationContext,能够与 reader 代理配合,好比与 XmlBeanDefinitionReader 一块儿读取 XML 配置文件:

GenericApplicationContext context = new GenericApplicationContext();
new XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml");
context.refresh();
复制代码

您能够应用同一个 ApplicationContext 读取不一样配置文件中的 bean 定义。能够经过 getBean 方法获取你定义 bean 的实例。ApplicationContext 接口有不少其余方法来获取 bean,但并不建议使用他们。实际上您的应用程序能够不使用任何 getBean 方法,所以就不会依赖 Spring API。好比 Spring 集成 web 框架并提供了依赖注入,好比 Controller bean 等,让您能够经过 metadata(元数据,如 @Autowired)在指定 bean 上声明依赖。

词汇

  1. Foremost 首先、最重要的;
  2. conceptually 概念上
  3. mature 成熟的
  4. whereby 经过
  5. mechanism ['mek(ə)nɪz(ə)m] 机制、原理;
  6. capable 有能力的
  7. internationalization 国际化
  8. assemble 集合、装配
  9. instruct 指导
  10. explicit 明确的
  11. suffice v. 足够
  12. boilerplate n. 样板文件
  13. convey 传达、运输
  14. correspond 一致、对应
  15. presentation [prez(ə)n'teɪʃ(ə)n] 展现、描述
  16. collaborating 合做,协做
  17. Schema ['skiːmə] 计划、模式
  18. slash [slæʃ] 斜线
  19. delegate [ˈdɛlɪˌɡeɪt; -ɡɪt; (for v.,) ˈdɛlɪˌɡeɪt] 代理、委派
相关文章
相关标签/搜索