spring中bean的生命週期

一、簡介
理解spring中bean的生命週期,對於學習和使用spring很有幫助。本文將從兩個角度對spring中bean
的生命週期進行介紹,一是bean定義生成;二是bean在初始化、使用、銷燬的生命週期中經歷的階段。
二、bean定義生成
bean定義生成主要分爲三個步驟,即bean定義的獲取、bean定義的註冊。
1、bean定義的獲取
bean的定義來源各種各樣,如xml定義、java註解定義等。
spring對各種來源提供了統一的接口org.springframework.core.io.Resource,
Resource接口即也是對spring內的所有底層資源進行了抽象(如file、url、classpath)。
Resource接口相關的類結構圖如下:

 

各類bean定義的加載請參數相應spring源碼。
2、bean定義的解析
由於來源的不同,bean的解析也是各種各樣的(如xml內標籤的解析)。
spring對bean的定義仍然有公共的接口org.springframework.beans.factory.config.BeanDefinition。
具體解析請查看spring源碼。
3、bean的註冊
解析得到的bean,最終會註冊到容器中,其實也就是ConcurrentHashMap,
即org.springframework.beans.factory.support.DefaultListableBeanFactory類中的實例變量

/** Map of bean definition objects, keyed by bean name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

此bean的加載完成
三、spring的生命週期
spring生命週期中的階段,包括初始化、使用、銷燬。
1、初始化階段
1)調用bean的構造函數,創建實例;
2)進行參數依賴注入;
3)若實現org.springframework.beans.BeanNameAware接口,則調用BeanNameAware的setBeanName()方法;
4)若實現org.springframework.beans.factory.BeanClassLoaderAware接口,則調用BeanClassLoaderAware的setBeanClassLoader()方法;
5)若實現org.springframework.context.ApplicationContextAware接口,則調用ApplicationContextAware的setApplicationContext()方法;
6)若使用了註解@PostConstruct,則調相應方法;
7)若實現org.springframework.beans.factory.InitializingBean接口,則調用InitializingBean接口的afterPropertiesSet方法;
8)若bean定義的使用了initMethod,則調相應方法;
9)若實現org.springframework.beans.factory.config.BeanPostProcessor接口,則調用BeanPostProcessor的postProcessBeforeInitialization()方法和postProcessAfterInitialization方法;
2、使用階段
1)bean在項目的使用;
3、銷燬階段
1)若使用註解@PreDestroy,則調用相應方法;
2)若bean定義中配置了destroyMethod,則調用相應方法;
3)若實現org.springframework.beans.factory.DisposableBean接口,則調用DisposableBean接口的destroy方法; 
四、bean生命週期示例
1、定義bean文件 SpringBeanLife.class

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

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

public class SpringBeanLife implements BeanNameAware, BeanClassLoaderAware, ApplicationContextAware,
        InitializingBean, BeanPostProcessor, DisposableBean {

    private String id;

    /******************* 下面是方法按時間執行的先後順序 *************************/
    //初始化
    SpringBeanLife() {
        System.out.println("bean init");
    }

    //參數注入
    public void setId(String id) {
        this.id = id;
        System.out.println("invoke set method");
    }

    //來自BeanNameAware
    @Override
    public void setBeanName(String name) {
        System.out.println("invoke setBeanName");
    }

    //來自BeanClassLoaderAware
    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println("invoke setBeanClassLoader");
    }

    //來自ApplicationContextAware
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("invoke setApplicationContext");
    }

    //來自注解@PostConstruct
    @PostConstruct
    public void postConstructMethod() {
        System.out.println("invoke postConstructMethod");
    }

    //來自InitializingBean
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("invoke afterPropertiesSet");
    }

    //來自配置initMethod = "initMethod"
    public void initMethod() {
        System.out.println("invoke init-method");
    }

    //來自BeanPostProcessor
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("invoke postProcessBeforeInitialization");
        return bean;
    }

    //來自BeanPostProcessor
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("invoke postProcessAfterInitialization");
        return bean;
    }

    //bean使用(如此時調用了下面的use方法)
    public void use() {
        System.out.println("use bean");
    }

    //來自注解@PreDestroy
    @PreDestroy
    public void preDestroyMethod() {
        System.out.println("invoke preDestroyMethod");
    }

    //來自bean定義中的配置destroyMethod = "destoryMethod"
    public void destoryMethod() {
        System.out.println("invoke destory-method");
    }

    //來自DisposableBean
    @Override
    public void destroy() throws Exception {
        System.out.println("invoke destroy");
    }
}

2、測試
 

import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;

@Configurable
public class SpringConfig {

    @Bean(initMethod = "initMethod", destroyMethod = "destoryMethod")
    public SpringBeanLife springBeanLife() {
        SpringBeanLife bean = new SpringBeanLife();
        bean.setId("001");
        return bean;
    }

    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
        SpringBeanLife bean = ctx.getBean(SpringBeanLife.class);
        bean.use();
        ctx.close();
    }
}

輸出:
bean init
invoke set method
invoke setBeanName
invoke setBeanClassLoader
invoke setApplicationContext
invoke postConstructMethod
invoke afterPropertiesSet
invoke init-method
invoke postProcessBeforeInitialization
invoke postProcessAfterInitialization
invoke postProcessBeforeInitialization
invoke postProcessAfterInitialization
use bean
invoke preDestroyMethod
invoke destroy
invoke destory-method
 

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