Spring官方文档(中文版!!!)

https://docs.spring.io/spring/docs/5.2.5.BUILD-SNAPSHOT/spring-framework-reference/images/prototype.png本文档是对spring官方文档的解读,原文档参见Spring官方文档

,本人只是翻译和整理,由于水平有限,部分解读可能不正确,欢迎提出更好的意见和建议!网页版移步我的临时网页

1 Spring综述

1.1 jdk环境依赖

从Spring Framework 5.1开始,Spring需要JDK 8+ (Java SE 8+),并提供对JDK 11 LTS的开箱即用支持。建议将Java SE 8 update 60作为Java 8的最低补丁版本,但通常建议使用最新的补丁版本。

1.2 spring介绍

The Spring Framework is divided into modules. Applications can choose which modules they need. At the heart are the modules of the core container, including a configuration model and a dependency injection mechanism. Beyond that, the Spring Framework provides foundational support for different application architectures, including messaging, transactional data and persistence, and web.

spring分为许多模块,应用可以选择他们需要的模块。它的核心模块是core container(也就是核心容器),包括配置模块和DI依赖注入。除此之外,Spring框架还为不同的应用程序体系结构提供基础支持,包括消息传递、事务数据和持久性以及web。

1.3 Spring历史

  • Spring框架的出现是为了解决早期J2EE规范的复杂性,他没有包括所有J2EE平台的规范,而是精心集成了一些特别的规范:
    • Servlet API (JSR 340)
    • WebSocket API (JSR 356)
    • Concurrency Utilities (JSR 236)
    • JSON Binding API (JSR 367)
    • Bean Validation (JSR 303)
    • JPA (JSR 338)
    • JMS (JSR 914)
    • as well as JTA/JCA setups for transaction coordination, if necessary.
    • the Dependency Injection (JSR 330) and Common Annotations (JSR 250) specifications(spring同样支持依赖注入和通用注解规范)
  • Spring5.0要求的最低Java版本为Java7

1.4 设计理念

在学习框架的时候,你不仅仅需要知道他是怎么使用和怎么做的,更需要了解他遵循的原则:

  • Provide choice at every level. 提供每个层次的选择,Spring允许您尽可能晚地推迟设计决策。例如你可以通过配置切换持久性提供程序(可能指的是类似数据源之类的)和基础设施以及第三方api集成。
  • Accommodate diverse perspectives.Spring embraces flexibility and is not opinionated about how things should be done. It supports a wide range of application needs with different perspectives.意思是spring是灵活多变的,支持广泛的应用程序需求。
  • Maintain strong backward compatibility. 具有强大的向后兼容性。Spring的发展已经被小心地管理,在不同的版本之间很少有中断的变化。Spring支持精心选择的JDK版本和第三方库,以方便维护依赖于Spring的应用程序和库。
  • Care about API design.关心api的设计。Spring团队投入了大量的思想和时间来开发直观的api,这些api可以支持多个版本和许多年。
  • Set high standards for code quality. 为代码质量设置高标准。它是少数几个可以声明干净的代码结构且包之间没有循环依赖关系的项目之一。

2. Core 核心

IoC Container, Events, Resources, i18n, Validation, Data Binding, Type Conversion, SpEL, AOP.

IoC(控制反转)容器,事件,资源,i18n,验证,数据绑定,类型转换,表达式,面向切面编程

2.1 IoC(Inversion of Control) Container

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.

项目的依赖(对象)仅通过构造器参数,工厂方法参数或者通过构造器或工厂方法返回的实例对象的set方法来定义他们的依赖(属性)。容器在bean对象创建时,将依赖注入到bean对象中。这个过程通过使用类的直接构造或服务定位模式机制,从根本上反转了bean本身控制实例化或依赖的位置

  • org.springframework.beans和 org.springframework.context是SpringIoC容器的基础
  • BeanFactory接口提供了能够管理任何类型对象的高级配置机制。
  • ApplicationContext时BeanFactory的一个子接口,他包含了:
    • 更容易与AOP特性集成 Easier integration with Spring’s AOP features
    • 消息资源处理 Message resource handling
    • 事件发布 Event publication
    • 特定于应用程序的Context(例如WebApplicationContext应用在web应用中) 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.

所以说,BeanFactory提供了配置框架和基础功能,ApplicationContext增加了更多特定功能。ApplicationContext时BeanFactory的一个完整超集,它在本章描述Spring的IoC容器时专用。

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及其之间的依赖关系反映在容器使用的配置元数据中。

2.1.1 补充

  • Service Locator Pattern:服务定位模式,一种设计模式。当我们希望使用JNDI查找来定位各种服务时,选择此种设计模式。这种设计模式使用了缓存技术。
    • 第一次需要服务时,服务定位器在JNDI中查找并缓存服务对象。
    • 再次查找相同的服务时,将在缓存中完成,提高了程序的性能
  • JNDI

2.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.

ApplicationContext这个接口就代表IoC容器,它负责实例化、配置和组装bean。容器通过读取配置文件的元数据来获取要实例化、配置和组装哪些对象的指令。配置文件支持xml,Java注解和纯Java代码。它允许您表达组成应用程序的对象以及这些对象之间丰富的相互依赖关系。

这个描述就是说对象的实例化,分配和管理由容器来负责,你只需要将这些信息用xml配置文件或注解或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

ApplicationContext的几个实现由Spring提供,通常你需要创建 ClassPathXmlApplicationContext或FileSystemXmlApplicationContext的实例。你也可以通过配置使用Java注解结合少量的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 Tools for Eclipse (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.

container magic

2.2.1 Configuration Metadata

  • 基于注解的配置:spring2.5+
  • 基于Java的配置:spring3.0+

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 elements inside a top-level element. Java configuration typically uses @Bean-annotated methods within a @Configuration class.

你可以在xml配置文件中使用标签或在带有@Configuration注解的java类中使用@Bean来定义Bean

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.

通常,不会在容器中配置细粒度域对象,因为通常由DAOs和业务逻辑负责创建和加载域对象,这时可以使用Spring与AspectJ的集成来配置在IoC容器控制之外创建的对象。

基于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. 用来标识单个bean
  • The class attribute defines the type of the bean and uses the fully qualified classname. 这个bean对应类的全限定名

2.2.2 实例化容器

ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

2.2.3 组合xml配置元数据 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.

让bean定义跨越多个XML文件可能很有用。通常,每个单独的XML配置文件表示体系结构中的逻辑层或模块。

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

    <bean id="bean1" class="..."/>
    <bean id="bean2" class="..."/>
</beans>

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,但是不要将配置文件耦合在系统的绝对路径,因为换了操作系统(在服务器部署)时很可能出问题。

2.2.4 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 requiredType), you can retrieve instances of your beans.

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

通过ApplicationContext接口的getBean方法获取Bean对象的实例。

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();

2.3 Bean Overview Bean对象概述

A Spring IoC container manages one or more beans. These beans are created with the configuration metadata that you supply to the container (for example, in the form of XML `` definitions).

一个springIoC容器管理着一个或多个bean对象,这些bean对象由你提供给容器的配置元数据创建生成。

Within the container itself, these bean definitions are represented as BeanDefinition objects, which contain (among other information) the following metadata:

在容器内部,这些bean定义表示为BeanDefinition对象,包含着以下元数据:

  • A package-qualified class name: typically, the actual implementation class of the bean being defined.(全限定类名)
  • Bean behavioral configuration elements, which state how the bean should behave in the container (scope, lifecycle callbacks, and so forth).(Bean的行为配置元素,作用域,生命周期回调等)
  • References to other beans that are needed for the bean to do its work. These references are also called collaborators or dependencies.(对该bean执行其工作所需的其他bean的引用。)
  • Other configuration settings to set in the newly created object — for example, the size limit of the pool or the number of connections to use in a bean that manages a connection pool.(在创建bean对象时的其他配置,如连接池的最大数量)
Property Explained in…
Class Instantiating Beans
Name Naming Beans
Scope Bean Scopes
Constructor arguments Dependency Injection
Properties Dependency Injection
Autowiring mode Autowiring Collaborators
Lazy initialization mode Lazy-initialized Beans
Initialization method Initialization Callbacks
Destruction method Destruction Callbacks

In addition to bean definitions that contain information on how to create a specific bean, the ApplicationContext implementations also permit the registration of existing objects that are created outside the container (by users). This is done by accessing the ApplicationContext’s BeanFactory through the getBeanFactory() method, which returns the BeanFactory DefaultListableBeanFactory implementation. DefaultListableBeanFactory supports this registration through the registerSingleton(..) and registerBeanDefinition(..) methods. However, typical applications work solely with beans defined through regular bean definition metadata.

这段话说我们可以通过ApplicationContext的getBeanFactory方法在容器之外创建对象,但是这种方法不被建议。//此处我找不到getBeanFactory这个方法。

Tip

Bean metadata and manually supplied singleton instances need to be registered as early as possible, in order for the container to properly reason about them during autowiring and other introspection steps. While overriding existing metadata and existing singleton instances is supported to some degree, the registration of new beans at runtime (concurrently with live access to the factory) is not officially supported and may lead to concurrent access exceptions, inconsistent state in the bean container, or both.

bean元数据和手动提供的单例实例需要尽早的注册,为了容器在自动装配和其他内省步骤中正确地推理它们。虽然在一定程度上支持覆盖现有元数据和现有单例实例,但是在运行时注册新bean(与对工厂的实时访问同时进行)不受官方支持,可能会导致并发访问异常,使bean容器中的不一致状态,或者两者都是。

2.3.1 Naming Beans 命名Bean

Every bean has one or more identifiers. These identifiers must be unique within the container that hosts the bean. A bean usually has only one identifier. However, if it requires more than one, the extra ones can be considered aliases.

每个bean都有一个或多个标识符。这些标识符在承载bean的容器中必须是惟一的。一个bean通常只有一个标识符。但是,如果需要多个别名,则可以将额外的别名视为别名。

In XML-based configuration metadata, you use the id attribute, the name attribute, or both to specify the bean identifiers. The id attribute lets you specify exactly one id. Conventionally, these names are alphanumeric (‘myBean’, ‘someService’, etc.), but they can contain special characters as well. If you want to introduce other aliases for the bean, you can also specify them in the name attribute, separated by a comma (,), semicolon (;), or white space.

用id配置标识,这个需要使唯一的,同时你还可以使用name来配置bean的别名,并且可以配置多个,你可以用逗号分号和空格来分开多个别名。

<bean id="user" class="com.leishida.spring.User" name="u us,use;user2"/>

You are not required to supply a name or an id for a bean. If you do not supply a name or id explicitly, the container generates a unique name for that bean. However, if you want to refer to that bean by name, through the use of the ref element or a Service Locator style lookup, you must provide a name. Motivations for not supplying a name are related to using inner beans and autowiring collaborators.

你也可以不为bean配置name和id属性,这样容器会为它自动分配唯一的id,但是你将无法引用它

Bean命名约定

The convention is to use the standard Java convention for instance field names when naming beans. That is, bean names start with a lowercase letter and are camel-cased from there. Examples of such names include accountManager, accountService, userDao, loginController, and so forth.

Naming beans consistently makes your configuration easier to read and understand. Also, if you use Spring AOP, it helps a lot when applying advice to a set of beans related by name.

遵循Java的命名规范,首字母小写,然后采用驼峰命名。

通过在类路径中扫描组件,Spring按照前面描述的规则为未命名的组件生成bean名称:本质上,使用简单的类名并将其初始字符转换为小写。但是,在(不寻常的)特殊情况下,如果有多个字符,并且第一个和第二个字符都是大写的,则保留原来的大小写。这些规则与java.beans.自省器.decapitalize (Spring在这里使用)定义的规则相同。

在bean定义外定义别名

<alias name="fromName" alias="toName"/>

2.3.2 Instantiating Beans 实例化Beans

If you use XML-based configuration metadata, you specify the type (or class) of object that is to be instantiated in the class attribute of the `` element. This class attribute (which, internally, is a Class property on a BeanDefinition instance) is usually mandatory. (For exceptions, see Instantiation by Using an Instance Factory Method and Bean Definition Inheritance.) You can use the Class property in one of two ways:

你通常必须指定class属性(因为要创建对象肯定要知道它的全类名)

你可以通过以下两种方式之一使用Class属性:

  • Typically, to specify the bean class to be constructed in the case where the container itself directly creates the bean by calling its constructor reflectively, somewhat equivalent to Java code with the new operator.直接通过反射创建
  • To specify the actual class containing the static factory method that is invoked to create the object, in the less common case where the container invokes a static factory method on a class to create the bean. The object type returned from the invocation of the static factory method may be the same class or another class entirely.通过静态工厂创建

Inner class names

If you want to configure a bean definition for a static nested class, you have to use the binary name of the nested class.

For example, if you have a class called SomeThing in the com.example package, and this SomeThing class has a static nested class called OtherThing, the value of the class attribute on a bean definition would be com.example.SomeThing$OtherThing.

Notice the use of the $ character in the name to separate the nested class name from the outer class name.

如果你想要配置一个静态内部类的bean,你需要这么写: packageName.OuterClassName$InnerClassName

Instantiation with a Constructor 使用构造器实例化

When you create a bean by the constructor approach, all normal classes are usable by and compatible with Spring. That is, the class being developed does not need to implement any specific interfaces or to be coded in a specific fashion. Simply specifying the bean class should suffice. However, depending on what type of IoC you use for that specific bean, you may need a default (empty) constructor.

当您通过构造函数方法创建一个bean时,所有的普通类都可以被Spring使用并与Spring兼容。也就是说,正在开发的类不需要实现任何特定的接口,也不需要以特定的方式进行编码。只需指定bean类就足够了。但是,根据您为特定bean使用的IoC类型,您可能需要一个默认(空)构造函数。

The Spring IoC container can manage virtually any class you want it to manage. It is not limited to managing true JavaBeans. Most Spring users prefer actual JavaBeans with only a default (no-argument) constructor and appropriate setters and getters modeled after the properties in the container. You can also have more exotic non-bean-style classes in your container. If, for example, you need to use a legacy connection pool that absolutely does not adhere to the JavaBean specification, Spring can manage it as well.

Spring IoC容器几乎可以管理您希望它管理的任何类。它不仅限于管理真正的javabean。大多数Spring用户更喜欢实际的javabean,它只有一个默认的(无参数的)构造函数,以及根据容器中的属性建模的适当的setter和getter方法。您还可以在容器中包含更多非bean风格的类。例如,如果您需要使用完全不符合JavaBean规范的遗留连接池,Spring也可以管理它。

With XML-based configuration metadata you can specify your bean class as follows:

<bean id="exampleBean" class="examples.ExampleBean"/>
<bean name="anotherExample" class="examples.ExampleBeanTwo"/>

有关构造器注入的细节,请移步注入依赖项[Injecting Dependencies]。

Instantiation with a Static Factory Method 使用静态工厂方法实例化

When defining a bean that you create with a static factory method, use the class attribute to specify the class that contains the static factory method and an attribute named factory-method to specify the name of the factory method itself. You should be able to call this method (with optional arguments, as described later) and return a live object, which subsequently is treated as if it had been created through a constructor. One use for such a bean definition is to call static factories in legacy code.

在定义使用静态工厂方法创建的bean时,使用class属性指定包含静态工厂方法的类,使用factory-method属性指定工厂方法本身的名称。您应该能够调用这个方法(带有可选参数,如后面所述)并返回一个活动对象,该对象随后被视为是通过构造函数创建的。这种bean定义的一个用途是在遗留代码中调用静态工厂。

The following bean definition specifies that the bean be created by calling a factory method. The definition does not specify the type (class) of the returned object, only the class containing the factory method. In this example, the createInstance() method must be a static method. The following example shows how to specify a factory method:

下面的bean定义指定通过调用工厂方法来创建bean。定义不指定返回对象的类型(类),只指定包含工厂方法的类。在本例中,createInstance()方法必须是一个静态方法。下面的例子展示了如何指定一个工厂方法:

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
   
   
    private String name;
    private int age;
}

public class UserFactory {
   
   

    public static User getUser(){
   
   
        return new User("工厂", 19);
    }
}
<bean id="user" class="com.leishida.spring.UserFactory" factory-method="getUser"/>
public void test(){
   
   
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Object user = context.getBean("user");
        System.out.println(user);   //User(name=工厂, age=19)
    }
Instantiation by Using an Instance Factory Method 使用实例工厂方法实例化

Similar to instantiation through a static factory method, instantiation with an instance factory method invokes a non-static method of an existing bean from the container to create a new bean. To use this mechanism, leave the class attribute empty and, in the factory-bean attribute, specify the name of a bean in the current (or parent or ancestor) container that contains the instance method that is to be invoked to create the object. Set the name of the factory method itself with the factory-method attribute. The following example shows how to configure such a bean:

与通过静态工厂方法实例化类似,使用实例工厂方法实例化将从容器中调用现有bean的非静态方法来创建新bean。要使用这种机制,将class属性保留为空,并在factory-bean属性中指定当前(或父或父)容器中bean的名称,该容器包含要调用来创建对象的实例方法。使用factory-method属性设置工厂方法本身的名称。下面的例子展示了如何配置这样一个bean:

public class InstanceUserFactory {
   
   
    private static User user = new User();

    public User createClientServiceInstance() {
   
   
        return user;
    }
}
<bean id="instanceUserFactory" class="com.leishida.spring.InstanceUserFactory"/>
<bean id="user1" factory-bean="instanceUserFactory" factory-method="createClientServiceInstance"/>
@org.junit.Test
    public void test2(){
   
   
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Object user = context.getBean("user1");
        System.out.println(user);   //User(name=null, age=0)
    }

一个工厂类也可以有多个工厂方法

TIP

In Spring documentation, “factory bean” refers to a bean that is configured in the Spring container and that creates objects through an instance or static factory method. By contrast, FactoryBean (notice the capitalization) refers to a Spring-specific FactoryBean .

意思使在spring文档里,factoryBean是你在配置里自己配置的工厂bean对象,而FactoryBean则值得是Spring的FactoryBean

2.4 Dependencies 依赖项

A typical enterprise application does not consist of a single object (or bean in the Spring parlance). Even the simplest application has a few objects that work together to present what the end-user sees as a coherent application. This next section explains how you go from defining a number of bean definitions that stand alone to a fully realized application where objects collaborate to achieve a goal.

典型的企业应用程序不包含单个对象(或Spring中的bean)。即使是最简单的应用程序也有几个对象一起工作,以呈现最终用户所看到的一致的应用程序。下一节将解释如何从定义许多独立的bean定义过渡到一个完全实现的应用程序,在这个应用程序中,对象通过协作来实现一个目标。

2.4.1 Dependency Injection 依赖注入

Dependency injection (DI) is a process whereby objects define their dependencies (that is, the other objects with which they work) 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 on its own by using direct construction of classes or the Service Locator pattern.

依赖项注入(DI)是一个过程,在这个过程中,对象仅通过构造函数参数、工厂方法的参数或从工厂方法构造或返回后在对象实例上设置的属性来定义它们的依赖项(即它们与之一起工作的其他对象)。然后容器在创建bean时注入这些依赖项。这个过程基本上是bean本身的逆过程(因此称为控制反转过程),由对象自己控制实例化或者定位他的依赖,改变为通过直接使用类的构造方法或者使用服务定位模式。

Code is cleaner with the DI principle, and decoupling is more effective when objects are provided with their dependencies. The object does not look up its dependencies and does not know the location or class of the dependencies. As a result, your classes become easier to test, particularly when the dependencies are on interfaces or abstract base classes, which allow for stub or mock implementations to be used in unit tests.

使用DI原则,代码更简洁,并且当对象提供其依赖项时,解耦更有效。对象不查找其依赖项,也不知道依赖项的位置或类。结果,您的类变得更容易测试,特别是当依赖关系在接口或抽象基类上时,这允许在单元测试中使用存根或模拟实现。

DI exists in two major variants: Constructor-based dependency injection and Setter-based dependency injection.

依赖注入存在与两个主要部分:基于构造器依赖注入和基于Set方法的依赖注入

Constructor-based Dependency Injection 基于构造器的依赖注入

Constructor-based DI is accomplished by the container invoking a constructor with a number of arguments, each representing a dependency. Calling a static factory method with specific arguments to construct the bean is nearly equivalent, and this discussion treats arguments to a constructor and to a static factory method similarly. The following example shows a class that can only be dependency-injected with constructor injection:

基于构造函数的DI是通过容器调用带有许多参数的构造函数来完成的,每个参数代表一个依赖项。调用带有特定参数的静态工厂方法来构造bean几乎是等价的,本讨论将参数分别用于构造函数和静态工厂方法。下面的例子展示了一个只能依赖注入构造函数注入的类:

Bean类:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
   
   
    private String name;
    private int age;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Score {
   
   
    private int English;
    private int Math;
}

XML配置

<bean id="user" class="com.leishida.spring.User">
        <constructor-arg name="name" value="构造器注入"/>
        <constructor-arg name="age" value="18"/>
        <!-- 当对象内部的属性是引用类型时,通过ref引用上面注册的score Bean -->
        <constructor-arg name="score" ref="score"/>
</bean>

测试

@org.junit.Test
    public void test3(){
   
   
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Object user = context.getBean("user");
        System.out.println(user);   //User(name=构造器注入, age=18, score=Score(English=0, Math=0))
    }

通过构造器注入时可以根据参数索引,类型,名称来注入

通过索引注入

<bean id="user1" class="com.leishida.spring.User">
        <constructor-arg index="0" value="索引"/>
        <constructor-arg index="1" value="18"/>
        <constructor-arg index="2" ref="score"/>
</bean>

通过类型注入

    <bean id="user2" class="com.leishida.spring.User">
        <constructor-arg type="java.lang.String" value="类型"/>
        <constructor-arg type="int" value="18"/>
        <constructor-arg type="com.leishida.spring.Score" ref="score"/>
    </bean>

通过名称匹配上面例子已经写过,此处不再赘述

Setter-based Dependency Injection 基于Set方法的注入

Setter-based DI is accomplished by the container calling setter methods on your beans after invoking a no-argument constructor or a no-argument static factory method to instantiate your bean.

The following example shows a class that can only be dependency-injected by using pure setter injection. This class is conventional Java. It is a POJO that has no dependencies on container specific interfaces, base classes, or annotations.

基于setter的DI是在调用无参数构造函数或无参数静态工厂方法来实例化bean之后,通过容器调用bean上的setter方法来完成的。

下面的示例显示了一个只能通过使用纯setter注入来依赖注入的类。这个类是传统的Java。它是一个不依赖于容器特定接口、基类或注释的POJO。

使用此种方式,一定要保证类对应的属性上有相应的get方法,否则会注入失败

The ApplicationContext supports constructor-based and setter-based DI for the beans it manages. It also supports setter-based DI after some dependencies have already been injected through the constructor approach. You configure the dependencies in the form of a BeanDefinition, which you use in conjunction with PropertyEditor instances to convert properties from one format to another. However, most Spring users do not work with these classes directly (that is, programmatically) but rather with XML bean definitions, annotated components (that is, classes annotated with @Component, @Controller, and so forth), or @Bean methods in Java-based @Configuration classes. These sources are then converted internally into instances of BeanDefinition and used to load an entire Spring IoC container instance.

ApplicationContext为它管理的bean支持基于构造函数和基于setter的DI。在通过构造函数方法注入了一些依赖项之后,它还支持基于setter的DI。您可以将依赖项配置为BeanDefinition的形式,并将其与PropertyEditor实例一起使用,以便将属性从一种格式转换为另一种格式。但是,大多数Spring用户并不直接使用这些类(也就是说,以编程的方式),而是使用XML bean定义、带注释的组件(也就是说,使用@Component、@Controller等注释的类)

Constructor-based or setter-based DI?

Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods for optional dependencies. Note that use of the @Required annotation on a setter method can be used to make the property be a required dependency; however, constructor injection with programmatic validation of arguments is preferable.

The Spring team generally advocates constructor injection, as it lets you implement application components as immutable objects and ensures that required dependencies are not null. Furthermore, constructor-injected components are always returned to the client (calling) code in a fully initialized state. As a side note, a large number of constructor arguments is a bad code smell, implying that the class likely has too many responsibilities and should be refactored to better address proper separation of concerns.

Setter injection should primarily only be used for optional dependencies that can be assigned reasonable default values within the class. Otherwise, not-null checks must be performed everywhere the code uses the dependency. One benefit of setter injection is that setter methods make objects of that class amenable to reconfiguration or re-injection later. Management through JMX MBeans is therefore a compelling use case for setter injection.

Use the DI style that makes the most sense for a particular class. Sometimes, when dealing with third-party classes for which you do not have the source, the choice is made for you. For example, if a third-party class does not expose any setter methods, then constructor injection may be the only available form of DI.

那么究竟是选择基于构造器的注入还是选择基于set方式的注入呢?这里官方给出了我们建议:

  • 如果你的set注入参数是必须的,那么你可以在set方法上加一个@Required注解来保证这个参数一定被注入
  • 最好使用带有参数编程式验证的构造函数注入,这样可以保证你需要的参数一定被注入
  • 大量的构造函数参数是一种不好的代码味道,这意味着类可能有太多的责任,应该对其进行重构,以更好地解决问题的适当分离。
  • Setter注入应该主要用于可选的依赖项,这些依赖项可以在类中分配合理的默认值。
  • 使用对特定类最有意义的DI样式。有时,在处理您没有源代码的第三方类时,需要为您做出选择。例如,如果第三方类没有公开任何setter方法,那么构造函数注入可能是惟一可用的DI形式。

使用set注入

    <bean id="user3" class="com.leishida.spring.User">
        <property name="name" value="set注入"/>
    </bean>
@org.junit.Test
    public void test4(){
   
   
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Object user = context.getBean("user3");
        System.out.println(user);       //User(name=set注入, age=0, score=null)
    }
Dependency Resolution Process 依赖性解析过程

The container performs bean dependency resolution as follows:

  • The ApplicationContext is created and initialized with configuration metadata that describes all the beans. Configuration metadata can be specified by XML, Java code, or annotations.
  • For each bean, its dependencies are expressed in the form of properties, constructor arguments, or arguments to the static-factory method (if you use that instead of a normal constructor). These dependencies are provided to the bean, when the bean is actually created.
  • Each property or constructor argument is an actual definition of the value to set, or a reference to another bean in the container.
  • Each property or constructor argument that is a value is converted from its specified format to the actual type of that property or constructor argument. By default, Spring can convert a value supplied in string format to all built-in types, such as int, long, String, boolean, and so forth.

容器执行bean依赖项解析如下:

  • ApplicationContext是用描述所有bean的配置元数据创建和初始化的。配置元数据可以由XML、Java代码或注释指定。
  • 对于每个bean,其依赖项都以属性、构造函数参数或静态工厂方法的参数的形式表示(如果您使用该方法而不是普通的构造函数)。这些依赖项是在bean实际创建时提供给bean的。
  • 每个属性或构造函数参数都是要设置的值的实际定义,或者是对容器中另一个bean的引用。
  • 值的每个属性或构造函数参数都从其指定的格式转换为该属性或构造函数参数的实际类型。默认情况下,Spring可以将以字符串格式提供的值转换为所有内置类型,如int、long、string、boolean等。

The Spring container validates the configuration of each bean as the container is created. However, the bean properties themselves are not set until the bean is actually created. Beans that are singleton-scoped and set to be pre-instantiated (the default) are created when the container is created. Scopes are defined in Bean Scopes. Otherwise, the bean is created only when it is requested. Creation of a bean potentially causes a graph of beans to be created, as the bean’s dependencies and its dependencies’ dependencies (and so on) are created and assigned. Note that resolution mismatches among those dependencies may show up late — that is, on first creation of the affected bean.

在创建容器时,Spring容器验证每个bean的配置。但是,在实际创建bean之前,不会设置bean属性本身。在创建容器时,将创建单例作用域的bean并将其设置为预实例化(默认值)。作用域是在Bean作用域中定义的。另外,仅在请求bean时才创建它。当bean的依赖项及其依赖项的依赖项(等等)被创建和分配时,bean的创建可能会创建一个bean图。注意解决依赖项延迟出现的不匹配问题,第一次创建将影响Bean。不是很懂最后一句

Circular dependencies

If you use predominantly constructor injection, it is possible to create an unresolvable circular dependency scenario.

For example: Class A requires an instance of class B through constructor injection, and class B requires an instance of class A through constructor injection. If you configure beans for classes A and B to be injected into each other, the Spring IoC container detects this circular reference at runtime, and throws a BeanCurrentlyInCreationException.

One possible solution is to edit the source code of some classes to be configured by setters rather than constructors. Alternatively, avoid constructor injection and use setter injection only. In other words, although it is not recommended, you can configure circular dependencies with setter injection.

Unlike the typical case (with no circular dependencies), a circular dependency between bean A and bean B forces one of the beans to be injected into the other prior to being fully initialized itself (a classic chicken-and-egg scenario).

循环依赖

如果主要使用构造函数注入,可能会创建无法解析的循环依赖场景。

例如:类A需要一个类B通过构造函数注入的实例,而类B需要一个类A通过构造函数注入的实例。如果您将bean配置为类A和B相互注入,Spring IoC容器将在运行时检测这个循环引用,并抛出一个BeanCurrentlyInCreationException异常。

一种可能的解决方案是编辑某些类的源代码,由setter注入而不是构造函数来注入。另外,避免构造函数注入,只使用setter注入。换句话说,尽管不建议这样做,但您可以使用setter注入配置循环依赖项。

与典型的情况(没有循环依赖关系)不同,bean A和bean B之间的循环依赖关系迫使一个bean在完全初始化之前被注入到另一个bean中(典型的先有鸡还是先有蛋的场景)。

下面来模拟一下循环依赖

首先两个JavaBean:

@AllArgsConstructor
public class Checken {
   
   
    private Egg
2.1. 简介 2.2. 控制反转(IoC)容器 2.2.1. 新的bean作用域 2.2.2. 更简单的XML配置 2.2.3. 可扩展的XML编写 2.2.4. Annotation(注解)驱动配置 2.2.5. 在classpath中自动搜索组件 2.3. 面向切面编程(AOP) 2.3.1. 更加简单的AOP XML配置 2.3.2. 对@AspectJ 切面的支持 2.3.3. 对bean命名pointcut( bean name pointcut element)的支持 2.3.4. 对AspectJ装载时织入(AspectJ load-time weaving)的支持 2.4. 中间层 2.4.1. 在XML里更为简单的声明性事务配置 2.4.2. 对Websphere 事务管理的完整支持 2.4.3. JPA 2.4.4. 异步的JMS 2.4.5. JDBC 2.5. Web层 2.5.1. Spring MVC合理的默认值 2.5.2. Portlet 框架 2.5.3. 基于Annotation的控制器 2.5.4. Spring MVC的表单标签库 2.5.5. 对Tiles 2 支持 2.5.6. 对JSF 1.2支持 2.5.7. JAX-WS支持 2.6. 其他 2.6.1. 动态语言支持 2.6.2. 增强的测试支持 2.6.3. JMX 支持 2.6.4. 将Spring 应用程序上下文部署为JCA adapter 2.6.5. 计划任务 2.6.6. 对Java 5 (Tiger) 支持 2.7. 移植到Spring 2.5 2.7.1. 改变 2.8. 更新的样例应用 2.9. 改进的文档 I. 核心技术 3. IoC(控制反转)容器 3.1. 简介 3.2. 基本原理 - 容器和bean 3.2.1. 容器 3.2.2. 实例化容器 3.2.3. 多种bean 3.2.4. 使用容器 3.3. 依赖 3.3.1. 注入依赖 3.3.2. 依赖配置详解 3.3.3. 使用depends-on 3.3.4. 延迟初始化bean 3.3.5. 自动装配(autowire)协作者 3.3.6. 依赖检查 3.3.7. 方法注入 3.4. Bean的作用域 3.4.1. Singleton作用域 3.4.2. Prototype作用域 3.4.3. Singleton beans和prototype-bean的依赖 3.4.4. 其他作用域 3.4.5. 自定义作用域 3.5. 定制bean特性 3.5.1. 生命周期回调 3.5.2. 了解自己 3.6. bean定义的继承 3.7. 容器扩展点 3.7.1. 用BeanPostProcessor定制bean 3.7.2. 用BeanFactoryPostProcessor定制配置元数据 3.7.3. 使用FactoryBean定制实例化逻辑 3.8. The ApplicationContext 3.8.1. BeanFactory 还是 ApplicationContext? 3.8.2. 利用MessageSource实现国际化 3.8.3. 事件 3.8.4. 底层资源的访问 3.8.5. ApplicationContext在WEB应用中的实例化 3.9. 粘合代码和可怕的singleton 3.10. 以J2EE RAR文件的形式部署Spring ApplicationContext 3.11. 基于注解(Annotation-based)的配置 3.11.1. @Autowired 3.11.2. 基于注解的自动连接微调 3.11.3. CustomAutowireConfigurer 3.11.4. @Resource 3.11.5. @PostConstruct 与 @PreDestroy 3.12. 对受管组件的Classpath扫描 3.12.1. @Component和更多典型化注解 3.12.2. 自动检测组件 3.12.3. 使用过滤器自定义扫描 3.12.4. 自动检测组件的命名 3.12.5. 为自动检测的组件提供一个作用域 3.12.6. 用注解提供限定符元数据 3.13. 注册一个LoadTimeWeaver 4. 资源 4.1. 简介 4.2. Resource接口 4.3. 内置 Resource 实现 4.3.1. UrlResource 4.3.2. ClassPathResource 4.3.3. FileSystemResource 4.3.4. ServletContextResource 4.3.5. InputStreamResource 4.3.6. ByteArrayResource 4.4. ResourceLoader接口 4.5. ResourceLoaderAware 接口 4.6. 把Resource作为属性来配置 4.7. Application context 和Resource 路径 4.7.1. 构造application context 4.7.2. Application context构造器中资源路径的通配符 4.7.3. FileSystemResource 说明 5. 校验,数据绑定,BeanWrapper,与属性编辑器 5.1. 简介 5.2. 使用Spring的Validator接口进行校验 5.3. 从错误代码到错误信息 5.4. Bean处理和BeanWrapper 5.4.1. 设置和获取属性值以及嵌套属性 5.4.2. 内建的PropertyEditor实现 6. 使用Spring进行面向切面编程(AOP) 6.1. 简介 6.1.1. AOP概念 6.1.2. Spring AOP的功能和目标 6.1.3. AOP代理 6.2. @AspectJ支持 6.2.1. 启用@AspectJ支持 6.2.2. 声明一个切面 6.2.3. 声明一个切入点(pointcut) 6.2.4. 声明通知 6.2.5. 引入(Introduction) 6.2.6. 切面实例化模型 6.2.7. 例子 6.3. 基于Schema的AOP支持 6.3.1. 声明一个切面 6.3.2. 声明一个切入点 6.3.3. 声明通知 6.3.4. 引入 6.3.5. 切面实例化模型 6.3.6. Advisor 6.3.7. 例子 6.4. AOP声明风格的选择 6.4.1. Spring AOP还是完全用AspectJ? 6.4.2. Spring AOP中使用@AspectJ还是XML? 6.5. 混合切面类型 6.6. 代理机制 6.6.1. 理解AOP代理 6.7. 以编程方式创建@AspectJ代理 6.8. 在Spring应用中使用AspectJ 6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点运算 7.2.3. AspectJ切入点表达式 7.2.4. 便利的切入点实现 7.2.5. 切入点的超类 7.2.6. 自定义切入点 7.3. Spring的通知API 7.3.1. 通知的生命周期 7.3.2. Spring里的通知类型 7.4. Spring里的Advisor API 7.5. 使用ProxyFactoryBean创建AOP代理 7.5.1. 基础 7.5.2. JavaBean属性 7.5.3. 基于JDK和CGLIB的代理 7.5.4. 对接口进行代理 7.5.5. 对类进行代理 7.5.6. 使用“全局”通知器 7.6. 简化代理定义 7.7. 使用ProxyFactory通过编程创建AOP代理 7.8. 操作被通知对象 7.9. 使用“自动代理(autoproxy)”功能 7.9.1. 自动代理bean定义 7.9.2. 使用元数据驱动的自动代理 7.10. 使用TargetSource 7.10.1. 热交换目标源 7.10.2. 池化目标源 7.10.3. 原型目标源 7.10.4. ThreadLocal目标源 7.11. 定义新的Advice类型 7.12. 更多资源 8. 测试 8.1. 简介 8.2. 单元测试 8.2.1. Mock对象 8.2.2. 单元测试支持类 8.3. 集成测试 8.3.1. 概览 8.3.2. 使用哪个支持框架 8.3.3. 通用目标 8.3.4. JDBC测试支持 8.3.5. 常用注解 8.3.6. JUnit 3.8遗留支持 8.3.7. Spring TestContext Framework 8.3.8. PetClinic示例 8.4. 更多资源 II. 中间层数据访问 9. 事务管理 9.1. 简介 9.2. 动机 9.3. 关键抽象 9.4. 使用资源同步的事务 9.4.1. 高层次方案 9.4.2. 低层次方案 9.4.3. TransactionAwareDataSourceProxy 9.5. 声明式事务管理 9.5.1. 理解Spring的声明式事务管理实现 9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. 有关的设置 9.5.6. 使用 @Transactional 9.5.7. 事务传播 9.5.8. 通知事务操作 9.5.9. 结合AspectJ使用 @Transactional 9.6. 编程式事务管理 9.6.1. 使用TransactionTemplate 9.6.2. 使用PlatformTransactionManager 9.7. 选择编程式事务管理还是声明式事务管理 9.8. 与特定应用服务器集成 9.8.1. IBM WebSphere 9.8.2. BEA WebLogic 9.8.3. Oracle OC4J 9.9. 常见问题的解决方法 9.9.1. 对一个特定的 DataSource 使用了错误的事务管理器 9.10. 更多的资源 10. DAO支持 10.1. 简介 10.2. 一致的异常层次 10.3. 一致的DAO支持抽象类 11. 使用JDBC进行数据访问 11.1. 简介 11.1.1. 选择一种工作模式 11.1.2. Spring JDBC包结构 11.2. 利用JDBC核心类控制JDBC的基本操作和错误处理 11.2.1. JdbcTemplate类 11.2.2. NamedParameterJdbcTemplate类 11.2.3. SimpleJdbcTemplate类 11.2.4. DataSource接口 11.2.5. SQLExceptionTranslator接口 11.2.6. 执行SQL语句 11.2.7. 执行查询 11.2.8. 更新数据库 11.2.9. 获取自动生成的主键 11.3. 控制数据库连接 11.3.1. DataSourceUtils类 11.3.2. SmartDataSource接口 11.3.3. AbstractDataSource类 11.3.4. SingleConnectionDataSource类 11.3.5. DriverManagerDataSource类 11.3.6. TransactionAwareDataSourceProxy类 11.3.7. DataSourceTransactionManager类 11.3.8. NativeJdbcExtractor 11.4. JDBC批量操作 11.4.1. 使用JdbcTemplate进行批量操作 11.4.2. 使用SimpleJdbcTemplate进行批量操作 11.5. 通过使用SimpleJdbc类简化JDBC操作 11.5.1. 使用SimpleJdbcInsert插入数据 11.5.2. 使用SimpleJdbcInsert来获取自动生成的主键 11.5.3. 指定SimpleJdbcInsert所使用的字段 11.5.4. 使用SqlParameterSource提供参数值 11.5.5. 使用SimpleJdbcCall调用存储过程 11.5.6. 声明SimpleJdbcCall使用的参数 11.5.7. 如何定义SqlParameters 11.5.8. 使用SimpleJdbcCall调用内置函数 11.5.9. 使用SimpleJdbcCall返回的ResultSet/REF Cursor 11.6. 用Java对象来表达JDBC操作 11.6.1. SqlQuery类 11.6.2. MappingSqlQuery类 11.6.3. SqlUpdate类 11.6.4. StoredProcedure类 11.6.5. SqlFunction类 11.7. 参数和数据处理的基本原则 11.7.1. 为参数设置SQL类型信息 11.7.2. 处理BLOB 和 CLOB对象 11.7.3. 在IN语句中传入一组参数值 11.7.4. 处理复杂类型的存储过程调用 12. 使用ORM工具进行数据访问 12.1. 简介 12.2. Hibernate 12.2.1. 资源管理 12.2.2. 在Spring容器中创建 SessionFactory 12.2.3. The HibernateTemplate 12.2.4. 不使用回调的基于Spring的DAO实现 12.2.5. 基于Hibernate3的原生API实现DAO 12.2.6. 编程式的事务划分 12.2.7. 声明式的事务划分 12.2.8. 事务管理策略 12.2.9. 容器资源 vs 本地资源 12.2.10. 在应用服务器中使用Hibernate的注意事项 12.3. JDO 12.3.1. 建立PersistenceManagerFactory 12.3.2. JdoTemplate和JdoDaoSupport 12.3.3. 基于原生的JDO API实现DAO 12.3.4. 事务管理 12.3.5. JdoDialect 12.4. Oracle TopLink 12.4.1. SessionFactory 抽象层 12.4.2. TopLinkTemplate and TopLinkDaoSupport 12.4.3. 基于原生的TopLink API的DAO实现 12.4.4. 事务管理 12.5. iBATIS SQL Maps 12.5.1. 创建SqlMapClient 12.5.2. 使用 SqlMapClientTemplate 和 SqlMapClientDaoSupport 12.5.3. 基于原生的iBATIS API的DAO实现 12.6. JPA 12.6.1. 在Spring环境中建立JPA 12.6.2. JpaTemplate 和 JpaDaoSupport 12.6.3. 基于原生的JPA实现DAO 12.6.4. 异常转化 12.7. 事务管理 12.8. JpaDialect III. The Web 13. Web MVC framework Web框架 13.1. 概述 13.1.1. 与其他MVC实现框架的集成 13.1.2. Spring Web MVC框架的特点 13.2. DispatcherServlet 13.3. 控制器 13.3.1. AbstractController 和 WebContentGenerator 13.3.2. 其它的简单控制器 13.3.3. MultiActionController 13.3.4. 命令控制器 13.4. 处理器映射(handler mapping) 13.4.1. BeanNameUrlHandlerMapping 13.4.2. SimpleUrlHandlerMapping 13.4.3. 拦截器(HandlerInterceptor) 13.5. 视图与视图解析 13.5.1. 视图解析器(ViewResolver) 13.5.2. 视图解析链 13.5.3. 重定向(Rediret)到另一个视图 13.6. 本地化解析器 13.6.1. AcceptHeaderLocaleResolver 13.6.2. CookieLocaleResolver 13.6.3. SessionLocaleResolver 13.6.4. LocaleChangeInterceptor 13.7. 使用主题 13.7.1. 简介 13.7.2. 如何定义主题 13.7.3. 主题解析器 13.8. Spring对分段文件上传(multipart file upload)的支持 13.8.1. 介绍 13.8.2. 使用MultipartResolver 13.8.3. 在表单中处理分段文件上传 13.9. 使用Spring的表单标签库 13.9.1. 配置 13.9.2. form标签 13.9.3. input标签 13.9.4. checkbox标签 13.9.5. checkboxes标签 13.9.6. radiobutton标签 13.9.7. radiobuttons标签 13.9.8. password标签 13.9.9. select标签 13.9.10. option标签 13.9.11. options标签 13.9.12. textarea标签 13.9.13. hidden标签 13.9.14. errors标签 13.10. 处理异常 13.11. 惯例优先原则(convention over configuration) 13.11.1. 对控制器的支持:ControllerClassNameHandlerMapping 13.11.2. 对模型的支持:ModelMap(ModelAndView) 13.11.3. 对视图的支持:RequestToViewNameTranslator 13.12. 基于注解的控制器配置 13.12.1. 建立dispatcher实现注解支持 13.12.2. 使用@Controller定义一个控制器 13.12.3. 使用@RequestMapping映射请求 13.12.4. 使用@RequestParam绑定请求参数到方法参数 13.12.5. 使用@ModelAttribute提供一个从模型到数据的链接 13.12.6. 使用@SessionAttributes指定存储在会话中的属性 13.12.7. 自定义WebDataBinder初始化 13.13. 更多资源 14. 集成视图技术 14.1. 简介 14.2. JSP和JSTL 14.2.1. 视图解析器 14.2.2. 'Plain-old' JSPs versus JSTL 'Plain-old' JSP与JSTL 14.2.3. 帮助简化开发的额外的标签 14.3. Tiles 14.3.1. 需要的资源 14.3.2. 如何集成Tiles 14.4. Velocity和FreeMarker 14.4.1. 需要的资源 14.4.2. Context 配置 14.4.3. 创建模板 14.4.4. 高级配置 14.4.5. 绑定支持和表单处理 14.5. XSLT 14.5.1. 写在段首 14.5.2. 小结 14.6. 文档视图(PDF/Excel) 14.6.1. 简介 14.6.2. 配置和安装 14.7. JasperReports 14.7.1. 依赖的资源 14.7.2. 配置 14.7.3. 构造ModelAndView 14.7.4. 使用子报表 14.7.5. 配置Exporter的参数 15. 集成其它Web框架 15.1. 简介 15.2. 通用配置 15.3. JavaServer Faces 15.3.1. DelegatingVariableResolver 15.3.2. FacesContextUtils 15.4. Struts 15.4.1. ContextLoaderPlugin 15.4.2. ActionSupport Classes 15.5. Tapestry 15.5.1. 注入 Spring 托管的 beans 15.6. WebWork 15.7. 更多资源 16. Portlet MVC框架 16.1. 介绍 16.1.1. 控制器 - MVC中的C 16.1.2. 视图 - MVC中的V 16.1.3. Web作用范围的Bean 16.2. DispatcherPortlet 16.3. ViewRendererServlet 16.4. 控制器 16.4.1. AbstractController 和 PortletContentGenerator 16.4.2. 其它简单的控制器 16.4.3. Command控制器 16.4.4. PortletWrappingController 16.5. 处理器映射 16.5.1. PortletModeHandlerMapping 16.5.2. ParameterHandlerMapping 16.5.3. PortletModeParameterHandlerMapping 16.5.4. 增加 HandlerInterceptors 16.5.5. HandlerInterceptorAdapter 16.5.6. ParameterMappingInterceptor 16.6. 视图和它们的解析 16.7. Multipart文件上传支持 16.7.1. 使用 PortletMultipartResolver 16.7.2. 处理表单里的文件上传 16.8. 异常处理 16.9. Portlet应用的部署 IV. 整合 17. 使用Spring进行远程访问与Web服务 17.1. 简介 17.2. 使用RMI暴露服务 17.2.1. 使用RmiServiceExporter暴露服务 17.2.2. 在客户端链接服务 17.3. 使用Hessian或者Burlap通过HTTP远程调用服务 17.3.1. 为Hessian和co.配置DispatcherServlet 17.3.2. 使用HessianServiceExporter暴露你的bean 17.3.3. 在客户端连接服务 17.3.4. 使用Burlap 17.3.5. 对通过Hessian或Burlap暴露的服务使用HTTP Basic认证 17.4. 使用HTTP调用器暴露服务 17.4.1. Exposing the service object 17.4.2. 在客户端连接服务 17.5. Web Services 17.5.1. 使用JAX-RPC暴露基于servlet的web服务 17.5.2. 使用JAX-RPC访问web服务 17.5.3. 注册JAX-RPC Bean映射 17.5.4. 注册自己的JAX-RPC 处理器 17.5.5. 使用JAX-WS暴露基于servlet的web服务 17.5.6. 使用JAX-WS暴露单独web服务 17.5.7. 使用Spring支持的JAX-WS RI来暴露服务 17.5.8. 使用JAX-WS访问web服务 17.5.9. 使用XFire来暴露Web服务 17.6. JMS 17.6.1. 服务端配置 17.6.2. 客户端配置 17.7. 对远程接口不提供自动探测实现 17.8. 在选择这些技术时的一些考虑 18. Enterprise Java Beans (EJB) 集成 18.1. 简介 18.2. 访问EJB 18.2.1. 概念 18.2.2. 访问本地的无状态Session Bean(SLSB) 18.2.3. 访问远程SLSB 18.2.4. Accessing EJB 2.x SLSBs versus EJB 3 SLSBs 18.3. 使用Spring提供的辅助类实现EJB组件 18.3.1. EJB 2.x base classes 18.3.2. EJB 3 注入拦截 19. JMS (Java Message Service) 19.1. 简介 19.2. 使用Spring JMS 19.2.1. JmsTemplate 19.2.2. 连接工厂 19.2.3. 目的地管理 19.2.4. 消息侦听容器 19.2.5. 事务管理 19.3. 发送消息 19.3.1. 使用消息转换器 19.3.2. SessionCallback 和 ProducerCallback 19.4. 接收消息 19.4.1. 同步接收 19.4.2. 异步接收 - 消息驱动的POJO 19.4.3. SessionAwareMessageListener接口 19.4.4. MessageListenerAdapter 19.4.5. 事务中的消息处理 19.5. JCA消息端点的支持 19.6. JMS命名空间支持 20. JMX 20.1. 介绍 20.2. 将Bean暴露为JMX 20.2.1. 创建MBeanServer 20.2.2. 重用原有的MBeanServer 20.2.3. 延迟初始化的MBean 20.2.4. MBean的自动注册 20.2.5. 控制注册行为 20.3. 控制Bean的管理接口 20.3.1. MBeanInfoAssembler接口 20.3.2. 使用源码级元数据 20.3.3. 使用JDK 5.0的注解 20.3.4. 源代码级的元数据类型 20.3.5. AutodetectCapableMBeanInfoAssembler接口 20.3.6. 用Java接口定义管理接口 20.3.7. 使用MethodNameBasedMBeanInfoAssembler 20.4. 控制Bean的ObjectName 20.4.1. 从Properties读取Properties 20.4.2. 使用MetadataNamingStrategy 20.4.3. 元素 20.5. JSR-160连接器 20.5.1. 服务器端连接器 20.5.2. 客户端连接器 20.5.3. 基于Burlap/Hessian/SOAP的JMX 20.6. 通过代理访问MBean 20.7. 通知 20.7.1. 为通知注册监听器 20.7.2. 发布通知 20.8. 更多资源 21. JCA CCI 21.1. 简介 21.2. 配置CCI 21.2.1. 连接器配置 21.2.2. 在Spring中配置ConnectionFactory 21.2.3. 配置CCI连接 21.2.4. 使用一个 CCI 单连接 21.3. 使用Spring的 CCI访问支持 21.3.1. 记录转换 21.3.2. CciTemplate类 21.3.3. DAO支持 21.3.4. 自动输出记录生成 21.3.5. 总结 21.3.6. 直接使用一个CCI Connection接口和Interaction接口 21.3.7. CciTemplate 使用示例 21.4. 建模CCI访问为操作对象 21.4.1. MappingRecordOperation 21.4.2. MappingCommAreaOperation 21.4.3. 自动生成输出记录 21.4.4. 总结 21.4.5. MappingRecordOperation 使用示例 21.4.6. MappingCommAreaOperation 使用示例 21.5. 事务 22. Spring邮件抽象层 22.1. 简介 22.2. 使用Spring邮件抽象 22.2.1. MailSender 和 SimpleMailMessage 的基本用法 22.2.2. 使用 JavaMailSender 和 MimeMessagePreparator 22.3. 使用MimeMessageHelper 22.3.1. 发送附件和嵌入式资源(inline resources) 22.3.2. 使用模板来创建邮件内容 23. Spring中的定时调度(Scheduling)和线程池(Thread Pooling) 23.1. 简介 23.2. 使用OpenSymphony Quartz 调度器 23.2.1. 使用JobDetailBean 23.2.2. 使用 MethodInvokingJobDetailFactoryBean 23.2.3. 使用triggers和SchedulerFactoryBean来包装任务 23.3. 使用JDK Timer支持类 23.3.1. 创建定制的timers 23.3.2. 使用 MethodInvokingTimerTaskFactoryBean类 23.3.3. 最后:使用TimerFactoryBean来设置任务 23.4. SpringTaskExecutor抽象 23.4.1. TaskExecutor接口 23.4.2. TaskExecutor类型 23.4.3. 使用TaskExecutor 24. 动态语言支持 24.1. 介绍 24.2. 第一个示例 24.3. 定义动态语言支持的bean 24.3.1. 公共概念 24.3.2. JRuby beans 24.3.3. Groovy beans 24.3.4. BeanShell beans 24.4. 场景 24.4.1. Spring MVC控制器的脚本化 24.4.2. Validator的脚本化 24.5. Bits and bobs 24.5.1. AOP - 通知脚本化bean 24.5.2. 作用域 24.6. 更多的资源 25. 注解和源代码级的元数据支持 25.1. 简介 25.2. Spring的元数据支持 25.3. 注解 25.3.1. @Required 25.3.2. Spring中的其它@Annotations 25.4. Jakarta Commons Attributes集成 25.5. 元数据和Spring AOP自动代理 25.5.1. 基本原理 25.5.2. 声明式事务管理 V. 示例程序 26. 演示案例 26.1. 介绍 26.2. 使用动态语言实现的Spring MVC控制器 26.2.1. 构建与部署 26.3. 使用SimpleJdbcTemplate和@Repository实现DAO 26.3.1. 域对象 26.3.2. Data Access Object 26.3.3. 构建 A. XML Schema-based configuration A.1. Introduction A.2. XML Schema-based configuration A.2.1. Referencing the schemas A.2.2. The util schema A.2.3. The jee schema A.2.4. The lang schema A.2.5. The jms schema A.2.6. The tx (transaction) schema A.2.7. The aop schema A.2.8. The context schema A.2.9. The tool schema A.2.10. The beans schema A.3. Setting up your IDE A.3.1. Setting up Eclipse A.3.2. Setting up IntelliJ IDEA A.3.3. Integration issues B. Extensible XML authoring B.1. Introduction B.2. Authoring the schema B.3. Coding a NamespaceHandler B.4. Coding a BeanDefinitionParser B.5. Registering the handler and the schema B.5.1. 'META-INF/spring.handlers' B.5.2. 'META-INF/spring.schemas' B.6. Using a custom extension in your Spring XML configuration B.7. Meatier examples B.7.1. Nesting custom tags within custom tags B.7.2. Custom attributes on 'normal' elements B.8. Further Resources C. spring-beans-2.0.dtd D. spring.tld D.1. Introduction D.2. The bind tag D.3. The escapeBody tag D.4. The hasBindErrors tag D.5. The htmlEscape tag D.6. The message tag D.7. The nestedPath tag D.8. The theme tag D.9. The transform tag E. spring-form.tld E.1. Introduction E.2. The checkbox tag E.3. The checkboxes tag E.4. The errors tag E.5. The form tag E.6. The hidden tag E.7. The input tag E.8. The label tag E.9. The option tag E.10. The options tag E.11. The password tag E.12. The radiobutton tag E.13. The radiobuttons tag E.14. The select tag E.15. The textarea tag F. Spring 2.5开发手册中文化项目 F.1. 声明 F.2. 致谢 F.3. 参与人员 F.4. 项目历程 表格清单 3.1. bean定义 3.2. Autowiring modes 3.3. 依赖检查方式 3.4. Bean作用域 3.5. Feature Matrix特性表 3.6. 内置事件 3.7. 过滤器类型 4.1. Resource strings 5.1. 属性示例 5.2. 内建的PropertyEditors 6.1. DefaultContextLoadTimeWeaver LoadTimeWeaversDefaultContextLoadTimeWeaver类和LoadTimeWeavers接口 6.2. aspectj-weaving属性值 9.1. 有关的设置 9.2. 设置 9.3. @Transactional 注解的属性 13.1. WebApplicationContext中特殊的bean 13.2. DispatcherServlet初始化参数 13.3. AbstractController提供的功能 13.4. 视图解析器 13.5. CookieLocaleResolver的属性 13.6. ThemeResolver的实现 14.1. 宏定义表 14.2. JasperReports View Classes 14.3. JasperReportsMultiFormatView默认Mapping Key映射 16.1. WebApplicationContext中特殊的Bean 16.2. DispatcherPortlet 的初始化参数 16.3. AbstractController提供的功能 19.1. JMS listener 元素的属性 19.2. JMS 元素的属性 19.3. JMS 元素的属性 20.1. 注册行为 20.2. 源代码级的元数据类型 20.3. 源代码级的元数据参数 21.1. Usage of Interaction execute methods 21.2. Usage of Interaction execute methods A.1. Eclipse XML editors D.1. Attributes D.2. Attributes D.3. Attributes D.4. Attributes D.5. Attributes D.6. Attributes D.7. Attributes D.8. Attributes E.1. Attributes E.2. Attributes E.3. Attributes E.4. Attributes E.5. Attributes E.6. Attributes E.7. Attributes E.8. Attributes E.9. Attributes E.10. Attributes E.11. Attributes E.12. Attributes E.13. Attributes E.14. Attributes
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值