Version 5.2.0.RELEASE
5.2.0版本
Core Technologies
一、核心技术
This part of the reference documentation covers all the technologies that are absolutely integral to the Spring Framework.
参考文档的这一部分涵盖了Spring框架必不可少的所有技术。
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.
其中最重要的是Spring框架的控制反转(IoC)容器。对Spring框架的IoC容器进行彻底处理之后,将全面介绍Spring的面向方面编程(AOP)技术。Spring框架拥有自己的AOP框架,该框架在概念上易于理解,并且成功解决了Java企业编程中AOP要求的80%的难题。
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.
还提供了Spring与AspectJ的集成(就功能而言,目前是最丰富的-当然肯定是Java企业领域中最成熟的AOP实现)。
1. The IoC Container
1. IoC容器
This chapter covers Spring’s Inversion of Control (IoC) container.
本章介绍了Spring的控制反转(IoC)容器。
1.1. Introduction to the Spring IoC Container and Beans
1.1. Spring IoC容器和Bean简介
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.
本章介绍了控制反转(IoC)原理的Spring框架实现。IoC也称为依赖注入(DI)。在此过程中,对象仅通过构造函数参数,工厂方法的参数或在构造或从工厂方法返回后在对象实例上设置的属性来定义其依赖项(即,与它们一起使用的其他对象) 。然后,容器在创建bean时注入那些依赖项。此过程从根本上讲是通过使用类的直接构造或诸如服务定位器模式之类的方法来控制其依赖项的实例化或位置的bean本身的逆过程(因此称为Control Inversion)。
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:
org.springframework.beans
和org.springframework.context
包是Spring框架的IoC容器的基础。BeanFactory接口提供了一种高级配置机制,能够管理任何类型的对象。 ApplicationContext是BeanFactory的子接口。它增加了
- 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.
- 更容易与Spring的AOP特性集成
- 消息资源处理(用于国际化)
- 事件发布
- 特定于应用程序层的上下文,如用于web应用程序的WebApplicationContext。
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.
简而言之,BeanFactory提供了配置框架和基本功能,并且ApplicationContext增加了更多针对企业的功能。ApplicationContext是BeanFactory的一个完整超集,在本章描述Spring的IoC容器时专门使用它。有关使用BeanFactory而不是ApplicationContext的更多信息,请参见BeanFactory相关文档。
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.
在Spring中,构成应用程序主干并由Spring IoC容器管理的对象称为bean。Bean是由Spring IoC容器实例化,组装和以其他方式管理的对象。否则,bean仅仅是应用程序中许多对象之一。Bean及其之间的依赖关系反映在容器使用的配置元数据中。
1.2. Container Overview
1.2. 容器概述
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.
org.springframework.context.ApplicationContext接口代表Spring IoC容器,并负责实例化,配置和组装Bean。容器通过读取配置元数据来获取有关要实例化,配置和组装哪些对象的指令。配置元数据以XML,Java注解或Java代码表示。它允许您表达组成应用程序的对象以及这些对象之间丰富的相互依赖关系。
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.
Spring提供了ApplicationContext接口的几种实现方式。在独立应用程序中,通常创建ClassPathXmlApplicationContext或FileSystemXmlApplicationContext的实例。尽管XML是定义配置元数据的传统格式,但是您可以通过提供少量XML配置来声明性地启用对这些其他元数据格式的支持,从而指示容器将Java注解或代码用作元数据格式。
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.
在大多数应用程序场景中,不需要显式的用户代码来实例化一个或多个Spring IoC容器实例。例如,在Web应用程序场景中,应用程序文件中在web.xml中写上8行左右的代码通常就足够了(请参阅Web应用程序的便捷ApplicationContext实例化)。如果使用 Spring Tool Suite(基于Eclipse的开发环境),则只需单击几次鼠标或击键即可轻松创建此样板配置。
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的工作原理的高级视图。您的应用程序类与配置元数据结合在一起,因此,在ApplicationContext
创建和初始化后,您将拥有一个完全配置且可执行的系统或应用程序。
图1. Spring IoC容器
1.2.1. Configuration Metadata
1.2.1. 配置元数据
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.
如上图所示,Spring IoC容器使用一种配置元数据形式。这个配置元数据表示您作为应用程序开发人员如何告诉Spring容器在应用程序中实例化,配置和组装对象。
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格式提供,这是本章大部分内容用来传达Spring IoC容器的关键概念和功能的内容。
note: 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.
注:基于XML的元数据不是配置元数据的唯一允许形式。Spring IoC容器本身与实际写入此配置元数据的格式完全脱钩。如今,许多开发人员为他们的Spring应用程序选择 基于Java的配置。
For information about using other forms of metadata with the Spring container, see:
有关在Spring容器中使用其他形式的元数据的信息,请参见:
- 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 2.5引入了对基于注解的配置元数据的支持。
- 基于Java的配置:从Spring 3.0开始,Spring JavaConfig项目提供的许多功能成为核心Spring Framework的一部分。因此,您可以使用Java而不是XML文件来定义应用程序类外部的bean。要使用这些新功能,请参阅 @Configuration, @Bean, @Import,和@DependsOn注解。
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.
Spring配置由容器必须管理的至少一个(通常是一个以上)bean定义组成。基于xml的配置元数据将这些bean配置为顶级<beans/>元素中的<bean/>元素。Java配置通常在@Configuration注解的类中使用@bean注解的方法。
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.
这些bean定义对应于组成应用程序的实际对象。通常,您定义服务层对象,数据访问对象(DAO),表示对象(例如Struts Action实例),基础结构对象(例如Hibernate SessionFactories,JMS Queues等)。通常,不会在容器中配置细粒度的域对象,因为创建和加载域对象通常是DAO和业务逻辑的职责。但是,您可以使用Spring与AspectJ的集成来配置在IoC容器的控制范围之外创建的对象。请参阅使用AspectJ与Spring依赖注入域对象。
The following example shows the basic structure of XML-based configuration metadata:
以下示例显示了基于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
https://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>
The id
attribute is a string that identifies the individual bean definition.
The class
attribute defines the type of the bean and uses the fully qualified classname.
注:id
属性是标识单个bean定义的字符串。
class
属性定义Bean的类型,并使用完全限定的类名。
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.
该id属性的值是指协作对象。在此示例中未显示用于引用协作对象的XML。有关更多信息,请参见 依赖项。
1.2.2. Instantiating a Container
1.2.2. 实例化一个容器
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
构造函数的一个或多个位置路径,这些资源字符串使容器可以从各种外部资源(例如本地文件系统,Java等)加载配置元数据CLASSPATH
。
new ClassPathXmlApplicationContext("services.xml", "daos.xml");
val context = ClassPathXmlApplicationContext("services.xml", "daos.xml")
note: 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.
注:在了解了Spring的IoC容器之后,您可能想了解更多有关Spring的 Resource抽象概念(如参考资料中所述),它提供了一种方便的机制,用于从URI语法中定义的位置读取InputStream。具体而言,Resource如应用程序上下文和资源路径中所述, 路径用于构造应用程序上下文。
The following example shows the service layer objects (services.xml)
configuration file:
下面的示例显示了服务层对象(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
https://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:
下面的示例显示了数据访问对象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
https://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.
在前面的示例中,服务层由的PetStoreServiceImpl
类和类型的两个数据访问对象JpaAccountDao
和JpaItemDao
(基于JPA对象关系映射标准)。该property name
元素是指JavaBean属性的名称,以及ref
元素指的是另一个bean定义的名称。id
和ref
元素之间的这种联系表达了协作对象之间的依赖性。有关配置对象的依赖关系的详细信息,请参见依赖关系。
Composing XML-based Configuration Metadata
组成基于XML的配置元数据
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.
使bean定义跨越多个XML文件可能很有用。通常,每个单独的XML配置文件都代表体系结构中的逻辑层或模块。
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:
您可以使用应用程序上下文构造函数从所有这些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>
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.
在前面的例子中,外部bean定义是从三个文件加载: services.xml
,messageSource.xml
,和themeSource.xml
。所有位置路径都相对于执行导入的定义文件,因此,services.xml必须与执行导入的文件位于相同的目录或类路径位置,messageSource.xml和
themeSource.xml
必须在resources
文件夹下,resources
文件夹必须与执行导入的文件位于相同的目录或类路径位置。可以看到,前面的斜杠被忽略了。但是,考虑到这些路径是相对的,所以最好不要使用斜杠。根据Spring模式,要导入的文件的内容,包括顶级的<beans/>元素,必须是有效的XML bean定义。
note: 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.
注:可以但不建议使用相对的“ ../”路径引用父目录中的文件。这样做会创建对当前应用程序外部文件的依赖。特别是,对于运行时解析过程选择“最近的”类路径根目录然后查找其父目录的classpath:
URL(例如classpath:../services.xml
),不建议使用此引用。类路径配置更改可能导致选择不同的、不正确的目录。
您始终可以使用完全限定的资源位置来代替相对路径:例如file:C:/config/services.xml
或classpath:/config/services.xml
。但是,请注意,您正在将应用程序的配置耦合到特定的绝对位置。通常最好为这样的绝对位置保留一个间接寻址,例如,通过在运行时针对JVM系统属性解析的“ $ {…}”占位符。
The namespace itself provides 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.
命名空间本身提供了导入指令功能。Spring提供的一系列XML名称空间(例如context
和util
名称空间)中提供了超出普通bean定义的其他配置功能。
The Groovy Bean Definition DSL
Groovy Bean定义DSL
As a further example for externalized configuration metadata, bean definitions can also be expressed in Spring’s Groovy Bean Definition DSL, as known from the Grails framework. Typically, such configuration live in a ".groovy" file with the structure shown in the following example:
作为外部化配置元数据的另一个示例,Bean定义也可以在Spring的Groovy Bean定义DSL中表达,这从Grails框架中可以知道。通常,这种配置位于“ .groovy”文件中,其结构如以下示例所示:
beans {
dataSource(BasicDataSource) {
driverClassName = "org.hsqldb.jdbcDriver"
url = "jdbc:hsqldb:mem:grailsDB"
username = "sa"
password = ""
settings = [mynew:"setting"]
}
sessionFactory(SessionFactory) {
dataSource = dataSource
}
myService(MyService) {
nestedBean = { AnotherBean bean ->
dataSource = dataSource
}
}
}
This configuration style is largely equivalent to XML bean definitions and even supports Spring’s XML configuration namespaces. It also allows for importing XML bean definition files through an importBeans
directive.
这种配置样式在很大程度上等同于XML bean定义,甚至支持Spring的XML配置名称空间。它还允许通过importBeans
指令导入XML bean定义文件。
1.2.3. Using the Container
1.2.3. 使用容器
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.
ApplicationContext
是一个维护bean定义以及相互依赖的注册表的高级工厂的接口。通过使用方法T getBean(String name, Class<T> requiredType)
,您可以检索bean的实例。
The ApplicationContext
lets you read bean definitions and access them, as the following example shows:
ApplicationContext允许您读取bean定义并访问它们,如下面的示例所示:
Java:
// 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();
Kotlin:
import org.springframework.beans.factory.getBean
// create and configure beans
val context = ClassPathXmlApplicationContext("services.xml", "daos.xml")
// retrieve configured instance
val service = context.getBean<PetStoreService>("petStore")
// use configured instance
var userList = service.getUsernameList()