Spring 生命週期回調機制

一、Spring 生命週期回調機制可選方式

Spring官方文檔註明從Spring 2.5開始,您可以使用三種方式來控制Bean生命週期行爲:

您可以組合以上這些機制來控制給定的 bean。

注:如果爲 bean 配置了多個生命週期機制,並且每個機制配置了不同的方法名稱,則每個配置的方法都按照下面的順序執行。但是,如果配置了相同的方法名稱 - 對於 example,init()用於初始化方法 - 對於多個這些生命週期機制,該方法將執行一次,如前一節中所述。(--翻譯自原文)

二、各種回調機制方式執行順序

爲同一bean配置的多個生命週期機制,使用不同的初始化方法,調用順序如下:

1、用@PostConstruct註解的方法

2、由InitializingBean回調接口定義的afterPropertiesSet()方法

3、自定義配置的init()方法(xml中的init-method或者@BeaninitMethod屬性)

銷燬方法調用順序相同:

1、用@PreDestroy註釋的方法

2、由DisposableBean回調接口定義的destroy()方法

3、自定義配置的destroy()方法(xml中的destroy-method或者@BeandestroyMethod屬性)

三、代碼測試

採用xml配置啓動Spring應用(Spring版本爲5.0.5.RELEASE):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!--開啓識別註解-->
    <context:annotation-config/>
    <bean id="x" class="com.dxc.opentalk.springtest.service.X" init-method="customInit"
    destroy-method="customDestroy">
    </bean>

    <bean id="y" class="com.dxc.opentalk.springtest.service.Y"></bean>
</beans>

測試類X:

package com.dxc.opentalk.springtest.service;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * @author dxc
 * @since 2020-02-10
 */
public class X implements InitializingBean, DisposableBean {

    @Autowired
    private Y y;

    private String s;

    public X() {
        System.out.println("Construct X");
    }

    /**三種初始化回調方法*/
    public void customInit() {
        System.out.println("init-method exec...");
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean exec...");
    }

    @PostConstruct
    public void annotationInit() {
        System.out.println("@PostConstruct exec...");
    }


    /**三種銷燬回調方法*/
    public void destroy() throws Exception {
        System.out.println("DisposableBean exec...");
    }

    public void customDestroy() {
        System.out.println("destroy-method exec...");
    }

    @PreDestroy
    public void annotationDestroy() {
        System.out.println("@PreDestroy exec...");
    }

}

啓動類:

package com.dxc.opentalk.springtest;

import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author dxc
 * @since 2020-02-29
 */
public class XmlBootStrap {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext applicationContext = new
                ClassPathXmlApplicationContext("applicationContext.xml");
        //關閉上下文,測試bean銷燬回調方法
        applicationContext.close();
    }
}

程序運行結果:

Construct X
Construct Y
@PostConstruct exec...
InitializingBean exec...
init-method exec...
@PreDestroy exec...
DisposableBean exec...
destroy-method exec...

可以看出,初始化回調方法以及銷燬回調方法與上述的順序一致。另外,需要說明的是如果這三種方式中的兩個或者三個用到一個方法上,那麼這個方法只會被調用一次。測試如下:

修改xml配置:

    <bean id="x" class="com.dxc.opentalk.springtest.service.X" init-method="afterPropertiesSet"
    destroy-method="destroy">
    </bean>

讓三種方式都配置到一個方法上:

package com.dxc.opentalk.springtest.service;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * @author dxc
 * @since 2020-02-10
 */
public class X implements InitializingBean, DisposableBean {

    @Autowired
    private Y y;

    private String s;

    public X() {
        System.out.println("Construct X");
    }


    public void customInit() {
        System.out.println("init-method exec...");
    }

    @PostConstruct
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean exec...");
    }


    public void annotationInit() {
        System.out.println("@PostConstruct exec...");
    }

    @PreDestroy
    public void destroy() throws Exception {
        System.out.println("DisposableBean exec...");
    }

    public void customDestroy() {
        System.out.println("destroy-method exec...");
    }


    public void annotationDestroy() {
        System.out.println("@PreDestroy exec...");
    }

}

程序運行結果如下:

Construct X
Construct Y
InitializingBean exec...
DisposableBean exec...

可見,這種情況下初始化回調方法和銷燬回調方法都只執行了一次。

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章