Spring 5.0.0框架介绍_中英文对照_3.6

博客:noahsnail.com  |  CSDN  |  简书

3.6 Customizing the nature of a bean

3.6.1 Lifecycle callbacks

To interact with the container’s management of the bean lifecycle, you can implement the Spring InitializingBean and DisposableBean interfaces. The container calls afterPropertiesSet() for the former and destroy() for the latter to allow the bean to perform certain actions upon initialization and destruction of your beans.


The JSR-250 @PostConstruct and @PreDestroy annotations are generally considered best practice for receiving lifecycle callbacks in a modern Spring application. Using these annotations means that your beans are not coupled to Spring specific interfaces. For details see Section 3.9.8, “@PostConstruct and @PreDestroy”.

If you don’t want to use the JSR-250 annotations but you are still looking to remove coupling consider the use of init-method and destroy-method object definition metadata.



Internally, the Spring Framework uses BeanPostProcessor implementations to process any callback interfaces it can find and call the appropriate methods. If you need custom features or other lifecycle behavior Spring does not offer out-of-the-box, you can implement a BeanPostProcessoryourself. For more information, see Section 3.8, “Container Extension Points”.


In addition to the initialization and destruction callbacks, Spring-managed objects may also implement the Lifecycle interface so that those objects can participate in the startup and shutdown process as driven by the container’s own lifecycle.


The lifecycle callback interfaces are described in this section.


Initialization callbacks

The org.springframework.beans.factory.InitializingBean interface allows a bean to perform initialization work after all necessary properties on the bean have been set by the container. The InitializingBean interface specifies a single method:


void afterPropertiesSet() throws Exception;

It is recommended that you do not use the InitializingBean interface because it unnecessarily couples the code to Spring. Alternatively, use the @PostConstruct annotation or specify a POJO initialization method. In the case of XML-based configuration metadata, you use the init-method attribute to specify the name of the method that has a void no-argument signature. With Java config, you use the initMethod attribute of @Bean, see the section called “Receiving lifecycle callbacks”. For example, the following:


<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>
public class ExampleBean {

    public void init() {
        // do some initialization work


…​is exactly the same as…​


<bean id="exampleInitBean" class="examples.AnotherExampleBean"/>
public class AnotherExampleBean implements InitializingBean {

    public void afterPropertiesSet() {
        // do some initialization work


but does not couple the code to Spring.


Destruction callbacks

Implementing the org.springframework.beans.factory.DisposableBean interface allows a bean to get a callback when the container containing it is destroyed. The DisposableBean interface specifies a single method:


void destroy() throws Exception;

It is recommended that you do not use the DisposableBean callback interface because it unnecessarily couples the code to Spring. Alternatively, use the @PreDestroy annotation or specify a generic method that is supported by bean definitions. With XML-based configuration metadata, you use the destroy-method attribute on the <bean/>. With Java config, you use the destroyMethod attribute of @Bean, see the section called “Receiving lifecycle callbacks”. For example, the following definition:


<bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="cleanup"/>
public class ExampleBean {

    public void cleanup() {
        // do some destruction work (like releasing pooled connections)


is exactly the same as:


<bean id="exampleInitBean" class="examples.AnotherExampleBean"/>
public class AnotherExampleBean implements DisposableBean {

    public void destroy() {
        // do some destruction work (like releasing pooled connections)


but does not couple the code to Spring.


The destroy-method attribute of a <bean> element can be assigned a special (inferred) value which instructs Spring to automatically detect a public close or shutdown method on the specific bean class (any class that implements java.lang.AutoCloseable or java.io.Closeable would therefore match). This special (inferred) value can also be set on the default-destroy-method attribute of a <beans> element to apply this behavior to an entire set of beans (see the section called “Default initialization and destroy methods”). Note that this is the default behavior with Java config.


Default initialization and destroy methods

When you write initialization and destroy method callbacks that do not use the Spring-specific InitializingBean and DisposableBean callback interfaces, you typically write methods with names such as init(), initialize(), dispose(), and so on. Ideally, the names of such lifecycle callback methods are standardized across a project so that all developers use the same method names and ensure consistency.


You can configure the Spring container to look for named initialization and destroy callback method names on every bean. This means that you, as an application developer, can write your application classes and use an initialization callback called init(), without having to configure an init-method="init" attribute with each bean definition. The Spring IoC container calls that method when the bean is created (and in accordance with the standard lifecycle callback contract described previously). This feature also enforces a consistent naming convention for initialization and destroy method callbacks.

你可以配置Spring容器查找每个bean的初始化方法和析构方法时的名字。这意味着,作为一个应用开发者,你可以编写应用程序类并使用名为init()的初始化回调方法,而不必在每个bean定义中配置init-method="init"特性。当bean创建时,Spring Ioc容器调用这个方法(按照前面描述的标准生命周期回调约定)。这个功能也强制了初始化方法和析构方法命名规范的一致性。

Suppose that your initialization callback methods are named init() and destroy callback methods are named destroy(). Your class will resemble the class in the following example.


public class DefaultBlogService implements BlogService {

    private BlogDao blogDao;

    public void setBlogDao(BlogDao blogDao) {
        this.blogDao = blogDao;

    // this is (unsurprisingly) the initialization callback method
    public void init() {
        if (this.blogDao == null) {
            throw new IllegalStateException("The [blogDao] property must be set.");
<beans default-init-method="init">

    <bean id="blogService" class="com.foo.DefaultBlogService">
        <property name="blogDao" ref="blogDao" />


The presence of the default-init-method attribute on the top-level <beans/> element attribute causes the Spring IoC container to recognize a method called init on beans as the initialization method callback. When a bean is created and assembled, if the bean class has such a method, it is invoked at the appropriate time.

位于顶层<beans/>元素中的default-init-method特性,会让Spring IoC容器将beans中的名为init的方法识别为初始化回调方法。当一个bean创建和组装时,如果bean类有这样一个方法,它会在恰当的时间被调用。

You configure destroy method callbacks similarly (in XML, that is) by using the default-destroy-method attribute on the top-level <beans/> element.


Where existing bean classes already have callback methods that are named at variance with the convention, you can override the default by specifying (in XML, that is) the method name using the init-method and destroy-method attributes of the <bean/> itself.


The Spring container guarantees that a configured initialization callback is called immediately after a bean is supplied with all dependencies. Thus the initialization callback is called on the raw bean reference, which means that AOP interceptors and so forth are not yet applied to the bean. A target bean is fully created first, then an AOP proxy (for example) with its interceptor chain is applied. If the target bean and the proxy are defined separately, your code can even interact with the raw target bean, bypassing the proxy. Hence, it would be inconsistent to apply the interceptors to the init method, because doing so would couple the lifecycle of the target bean with its proxy/interceptors and leave strange semantics when your code interacts directly to the raw target bean.


Combining lifecycle mechanisms

As of Spring 2.5, you have three options for controlling bean lifecycle behavior: the InitializingBean and DisposableBean callback interfaces; custom init() and destroy() methods; and the @PostConstruct and @PreDestroy annotations. You can combine these mechanisms to control a given bean.

从Spring 2.5开始,在控制bean的生命周期行为时,你有三中选择:InitializingBeanDisposableBean回调接口;定制init()destroy()方法;@PostConstruct@PreDestroy`注解。在控制一个给定bean时你可以组合这些机制。

If multiple lifecycle mechanisms are configured for a bean, and each mechanism is configured with a different method name, then each configured method is executed in the order listed below. However, if the same method name is configured - for example, init() for an initialization method - for more than one of these lifecycle mechanisms, that method is executed once, as explained in the preceding section.


Multiple lifecycle mechanisms configured for the same bean, with different initialization methods, are called as follows:

  • Methods annotated with @PostConstruct

  • afterPropertiesSet() as defined by the InitializingBean callback interface

  • A custom configured init() method


  • 先调用有注解@PostConstruct的方法

  • 然后调用InitializingBean回调接口定义的afterPropertiesSet()方法

  • 最好调用定制配置的init()方法

Destroy methods are called in the same order:

  • Methods annotated with @PreDestroy

  • destroy() as defined by the DisposableBean callback interface

  • A custom configured destroy() method


  • 先调用有@PreDestroy注解的方法

  • 再调用DisposableBean回调接口定义的destroy()方法

  • 最好调用定制配置的destroy()方法

Startup and shutdown callbacks

The Lifecycle interface defines the essential methods for any object that has its own lifecycle requirements (e.g. starts and stops some background process):


public interface Lifecycle {

    void start();

    void stop();

    boolean isRunning();


Any Spring-managed object may implement that interface. Then, when the ApplicationContext itself receives start and stop signals, e.g. for a stop/restart scenario at runtime, it will cascade those calls to all Lifecycle implementations defined within that context. It does this by delegating to a LifecycleProcessor:


public interface LifecycleProcessor extends Lifecycle {

    void onRefresh();

    void onClose();


Notice that the LifecycleProcessor is itself an extension of the Lifecycle interface. It also adds two other methods for reacting to the context being refreshed and closed.


Note that the regular org.springframework.context.Lifecycle interface is just a plain contract for explicit start/stop notifications and does NOT imply auto-startup at context refresh time. Consider implementing org.springframework.context.SmartLifecycle instead for fine-grained control over auto-startup of a specific bean (including startup phases). Also, please note that stop notifications are not guaranteed to come before destruction: On regular shutdown, all Lifecycle beans will first receive a stop notification before the general destruction callbacks are being propagated; however, on hot refresh during a context’s lifetime or on aborted refresh attempts, only destroy methods will be called.

注意正规的org.springframework.context.Lifecycle接口只是一个显式启动/关闭通知的协议,并不意味着在上下文刷新时自动启动。考虑实现org.springframework.context.SmartLifecycle接口来实现对指定bean自动启动的细粒度控制(包括启动时期)。请注意停止通知不能保证在销毁之前到来:在正式关闭时,所有的Lifecycle beans在通常的析构回调传播之前首先会收到停止通知;但是,在上下文使用期间进行热刷新或尝试取消再刷新,只会调用析构方法。

The order of startup and shutdown invocations can be important. If a "depends-on" relationship exists between any two objects, the dependent side will start after its dependency, and it will stop before its dependency. However, at times the direct dependencies are unknown. You may only know that objects of a certain type should start prior to objects of another type. In those cases, the SmartLifecycle interface defines another option, namely the getPhase() method as defined on its super-interface, Phased.


public interface Phased {
    int getPhase();
public interface SmartLifecycle extends Lifecycle, Phased {
    boolean isAutoStartup();
    void stop(Runnable callback);

When starting, the objects with the lowest phase start first, and when stopping, the reverse order is followed. Therefore, an object that implements SmartLifecycle and whose getPhase() method returns Integer.MIN_VALUE would be among the first to start and the last to stop. At the other end of the spectrum, a phase value of Integer.MAX_VALUE would indicate that the object should be started last and stopped first (likely because it depends on other processes to be running). When considering the phase value, it’s also important to know that the default phase for any "normal" Lifecycle object that does not implement SmartLifecycle would be 0. Therefore, any negative phase value would indicate that an object should start before those standard components (and stop after them), and vice versa for any positive phase value.


As you can see the stop method defined by SmartLifecycle accepts a callback. Any implementation must invoke that callback’s run() method after that implementation’s shutdown process is complete. That enables asynchronous shutdown where necessary since the default implementation of the LifecycleProcessor interface, DefaultLifecycleProcessor, will wait up to its timeout value for the group of objects within each phase to invoke that callback. The default per-phase timeout is 30 seconds. You can override the default lifecycle processor instance by defining a bean named "lifecycleProcessor" within the context. If you only want to modify the timeout, then defining the following would be sufficient:


<bean id="lifecycleProcessor" class="org.springframework.context.support.DefaultLifecycleProcessor">
    <!-- timeout value in milliseconds -->
    <property name="timeoutPerShutdownPhase" value="10000"/>

As mentioned, the LifecycleProcessor interface defines callback methods for the refreshing and closing of the context as well. The latter will simply drive the shutdown process as if stop() had been called explicitly, but it will happen when the context is closing. The refresh callback on the other hand enables another feature of SmartLifecycle beans. When the context is refreshed (after all objects have been instantiated and initialized), that callback will be invoked, and at that point the default lifecycle processor will check the boolean value returned by each SmartLifecycle object’s isAutoStartup() method. If "true", then that object will be started at that point rather than waiting for an explicit invocation of the context’s or its own start() method (unlike the context refresh, the context start does not happen automatically for a standard context implementation). The "phase" value as well as any "depends-on" relationships will determine the startup order in the same way as described above.

像上面提到的那样,LifecycleProcessor接口为再刷新和上下文的关闭也定义了回调方法。后者会简单的驱动关闭进程就像显式的调用了stop()方法一样,但当上下文关闭时它才会发生。另一方面refresh回调能使SmartLifecycle beans的另一个功能可用。当上下文再刷新时(所有对象已经实例化并初始化),回调函数将被调用,那时默认的生命周期处理器将会检查每个SmartLifecycle对象的isAutoStartup()方法返回的布尔值。如果为true,对象将会在那时启动而不是等待上下文的显式调用或它自己的start()方法(不像上下文再刷新,对于一个标准的上下文实现上下启动不会自动发生)。"phase"值以及"depends-on"关系将决定启动顺序,像上面描述的一样。

Shutting down the Spring IoC container gracefully in non-web applications

This section applies only to non-web applications. Spring’s web-based ApplicationContext implementations already have code in place to shut down the Spring IoC container gracefully when the relevant web application is shut down.

这一节只应用于非web应用。Spring的基于web的ApplicationContext实现已经有代码来处理当相关的web应用关闭时,妥善关闭Spring IoC容器的问题。

If you are using Spring’s IoC container in a non-web application environment; for example, in a rich client desktop environment; you register a shutdown hook with the JVM. Doing so ensures a graceful shutdown and calls the relevant destroy methods on your singleton beans so that all resources are released. Of course, you must still configure and implement these destroy callbacks correctly.


To register a shutdown hook, you call the registerShutdownHook() method that is declared on the ConfigurableApplicationContext interface:


import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public final class Boot {

    public static void main(final String[] args) throws Exception {

        ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext(
                new String []{"beans.xml"});

        // add a shutdown hook for the above context...

        // app runs here...

        // main method exits, hook is called prior to the app shutting down...


3.6.2 ApplicationContextAware and BeanNameAware

When an ApplicationContext creates an object instance that implements the org.springframework.context.ApplicationContextAware interface, the instance is provided with a reference to that ApplicationContext.


public interface ApplicationContextAware {

    void setApplicationContext(ApplicationContext applicationContext) throws BeansException;


Thus beans can manipulate programmatically the ApplicationContext that created them, through the ApplicationContext interface, or by casting the reference to a known subclass of this interface, such as ConfigurableApplicationContext, which exposes additional functionality. One use would be the programmatic retrieval of other beans. Sometimes this capability is useful; however, in general you should avoid it, because it couples the code to Spring and does not follow the Inversion of Control style, where collaborators are provided to beans as properties. Other methods of the ApplicationContext provide access to file resources, publishing application events, and accessing a MessageSource. These additional features are described in Section 3.15, “Additional Capabilities of the ApplicationContext”.


As of Spring 2.5, autowiring is another alternative to obtain reference to the ApplicationContext. The "traditional" constructor and byTypeautowiring modes (as described in Section 3.4.5, “Autowiring collaborators”) can provide a dependency of type ApplicationContext for a constructor argument or setter method parameter, respectively. For more flexibility, including the ability to autowire fields and multiple parameter methods, use the new annotation-based autowiring features. If you do, the ApplicationContext is autowired into a field, constructor argument, or method parameter that is expecting the ApplicationContext type if the field, constructor, or method in question carries the @Autowired annotation. For more information, see Section 3.9.2, “@Autowired”.

从Spring 2.5起,自动装配是另一种可替代的获得ApplicationContext引用的方法。『传统的』constructorbyType自动装配模式(如3.4.5小节所述,『自动装配协作者』)可以分别为构造函数参数或setter方法参数提供ApplicationContext类型的依赖。更多的灵活性包括自动装配变量的能力和多参数方法,使用新的基于注解的自动装配特性。如果你这一做的话,ApplicationContext可以被自动装配到变量中,构造函数参数中或方法参数中,如果讨论的变量,构造函数或方法有@Autowired注解,那么可以期望它是ApplicationContext类型。更多信息请看3.9.2小节,@autowired

When an ApplicationContext creates a class that implements the org.springframework.beans.factory.BeanNameAware interface, the class is provided with a reference to the name defined in its associated object definition.


public interface BeanNameAware {

    void setBeanName(String name) throws BeansException;


The callback is invoked after population of normal bean properties but before an initialization callback such as InitializingBean afterPropertiesSet or a custom init-method.


3.6.3 Other Aware interfaces

Besides ApplicationContextAware and BeanNameAware discussed above, Spring offers a range of Aware interfaces that allow beans to indicate to the container that they require a certain infrastructure dependency. The most important Aware interfaces are summarized below - as a general rule, the name is a good indication of the dependency type:


Table 3.4. Aware interfaces

Name Injected Dependency Explained in
ApplicationContextAware Declaring ApplicationContext Section 3.6.2, “ApplicationContextAware and BeanNameAware”
ApplicationEventPublisherAware Event publisher of the enclosing ApplicationContext Section 3.15, “Additional Capabilities of the ApplicationContext”
BeanClassLoaderAware Class loader used to load the bean classes. Section 3.3.2, “Instantiating beans”
BeanFactoryAware Declaring BeanFactory Section 3.6.2, “ApplicationContextAware and BeanNameAware”
BeanNameAware Name of the declaring bean Section 3.6.2, “ApplicationContextAware and BeanNameAware”
BootstrapContextAware Resource adapter BootstrapContext the container runs in. Typically available only in JCA aware ApplicationContexts Chapter 28, JCA CCI
LoadTimeWeaverAware Defined weaver for processing class definition at load time Section 7.8.4, “Load-time weaving with AspectJ in the Spring Framework”
MessageSourceAware Configured strategy for resolving messages (with support for parametrization and internationalization) Section 3.15, “Additional Capabilities of the ApplicationContext”
NotificationPublisherAware Spring JMX notification publisher Section 27.7, “Notifications”
ResourceLoaderAware Configured loader for low-level access to resources Chapter 4, Resources
ServletConfigAware Current ServletConfig the container runs in. Valid only in a web-aware Spring ApplicationContext Chapter 18, Web MVC framework
ServletContextAware Current ServletContext the container runs in. Valid only in a web-aware Spring ApplicationContext Chapter 18, Web MVC framework

表3.4. Aware接口

Name Injected Dependency Explained in
ApplicationContextAware 声明ApplicationContext Section 3.6.2, “ApplicationContextAware and BeanNameAware”
ApplicationEventPublisherAware 封装事件发布的ApplicationContext Section 3.15, “Additional Capabilities of the ApplicationContext”
BeanClassLoaderAware 用来加载bean的类加载器 Section 3.3.2, “Instantiating beans”
BeanFactoryAware 声明BeanFactory Section 3.6.2, “ApplicationContextAware and BeanNameAware”
BeanNameAware 声明的bean的名字 Section 3.6.2, “ApplicationContextAware and BeanNameAware”
BootstrapContextAware 容器运行的资源自适应BootstrapContext. 通常只在JCA aware ApplicationContexts可获得 Chapter 28, JCA CCI
LoadTimeWeaverAware 加载时为处理类定义定义的weaver Section 7.8.4, “Load-time weaving with AspectJ in the Spring Framework”
MessageSourceAware 解析消息配置策略 (支持参数化和国际化) Section 3.15, “Additional Capabilities of the ApplicationContext”
NotificationPublisherAware Spring JMX通知发布器 Section 27.7, “Notifications”
ResourceLoaderAware 为底层访问资源配置的加载器 Chapter 4, Resources
ServletConfigAware 容器运行的当前ServletConfig。 仅在web感知的Spring ApplicationContext中有效 Chapter 18, Web MVC framework
ServletContextAware 容器运行的当前ServletContext。 仅在web感知的Spring ApplicationContext中有效 Chapter 18, Web MVC framework

Note again that usage of these interfaces ties your code to the Spring API and does not follow the Inversion of Control style. As such, they are recommended for infrastructure beans that require programmatic access to the container.