Spring IoC-Bean生命週期

概述

通過依賴注入的方式, 將Bean的生命週期交由容器(ApplicationContext)來管理. 一個Bean生命周是指bean的初始化開始到最終銷燬的一段時間, 這是一個Bean的完整的週期過程. 在Spring IoC容器中, 爲用戶提供了各類回調來使得用戶感知bean的生命週期.

Bean生命週期感知回調

BeanFactory容器定義的Bean生命週期回調

BeanFactory容器應該儘可能提供的感知回調(具體請參考BeanFactory的參考頁面), 節選部分:
在這裏插入圖片描述

實現Bean生命週期回調示例

java代碼

public class User implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean,
        EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware, ApplicationEventPublisherAware,
        MessageSourceAware, ApplicationContextAware{
    private int id;
    private String name;
    private int age;

    public User() {
        System.out.println("[Constructor] init the bean");
    }

    public void setId(int id) {
        System.out.println("[setId] set the id, value: " + id);
        this.id = id;
    }

    public void setName(String name) {
        System.out.println("[setName] set the name, value: " + name);
        this.name = name;
    }

    public void setAge(int age) {
        System.out.println("[setAge] set the age, value: " + age);
        this.age = age;
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("[setBeanFactory] set the beanFactory, value: ");
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("[setBeanName] set the bean name, value: " + name);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("[afterPropertiesSet] afterPropertiesSet.");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("[destroy] destroy.");
    }

    @PostConstruct
    public void postConstruct() {
        System.out.println("[postConstruct] postConstruct.");
    }

    @PreDestroy
    public void preDestroy() {
        System.out.println("[preDestroy] preDestroy.");
    }

    @Override
    public void setEnvironment(Environment environment) {
        System.out.println("[setEnvironment] set the environment, value: ");
    }

    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        System.out.println("[setEmbeddedValueResolver] set the resolver, value: ");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("[setApplicationContext] set the applicationContext, value: ");
    }

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        System.out.println("[setApplicationEventPublisher] set the applicationEventPublisher, value: ");
    }

    @Override
    public void setMessageSource(MessageSource messageSource) {
        System.out.println("[setMessageSource] set the messageSource, value: ");
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        System.out.println("[setResourceLoader] set the resourceLoader, value: ");
    }
}

// BeanFactory相關, 這個其實不是bean的生命週期, 是容器的生命週期
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    // BeanFactory準備好之後
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("[postProcessBeanFactory]");
        BeanDefinition bd = beanFactory.getBeanDefinition("user");
        bd.getPropertyValues().addPropertyValue("name", "Walter New");
    }
}

//. 與銷燬有關的接口
public class MyDestructionAwareBeanPostProcessor implements DestructionAwareBeanPostProcessor {
    // 銷燬之前
    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
        System.out.println("[postProcessBeforeDestruction]");
    }

    // 我也不知道
    @Override
    public boolean requiresDestruction(Object bean) {
        System.out.println("[requiresDestruction]");
        return false;
    }

    // 初始化之前
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("[postProcessBeforeInitialization]");
        return bean;
    }

    // 初始化之後
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("[postProcessAfterInitialization]");
        return bean;
    }
}

// 關於Bean初始化的後置處理器
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
    public MyInstantiationAwareBeanPostProcessor() {
        super();
        System.out.println("[UserInstantiationAwareBeanPostProcessor] init the UserInstantiationAwareBeanPostProcessor");
    }

    // 當初始化bean之前
    @Override
    public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
        System.out.println("[postProcessBeforeInstantiation]");
        return null;
    }

    // 當初始化bean之後
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("[postProcessAfterInitialization]");
        return null;
    }

    // 當設置晚了properties之後
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
            throws BeansException {
        System.out.println("[postProcessPropertyValues]");
        return null;
    }
}

public class LifecylceDemo {
    public static void main(String[] args) throws InterruptedException {
        String cfg1 = "classpath:application-lifecycle.xml";
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(cfg1);
        System.out.println("context init completed");
        System.out.println("start to shutdown the context");
        context.registerShutdownHook();
    }
}

bean的配置文件 classpath:application-lifecycle.xml

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
       default-autowire="byName">

    <bean id="user" class="lab.anoper.ioc.lifecycle.User" init-method="postConstruct" destroy-method="preDestroy">
        <property name="id" value="1"/>
        <property name="name" value="Walter Yan"/>
        <property name="age" value="25"/>
    </bean>

    <bean id="beanPostProcessor" class="lab.anoper.ioc.lifecycle.MyInstantiationAwareBeanPostProcessor"/>
    <bean id="userBeanFactoryPostProcessor" class="lab.anoper.ioc.lifecycle.MyBeanFactoryPostProcessor"/>
    <bean id="myDestructionAwareBeanPostProcessor"
          class="lab.anoper.ioc.lifecycle.MyDestructionAwareBeanPostProcessor"/>
</beans>

輸出結果:

[postProcessBeanFactory]
[MyInstantiationAwareBeanPostProcessor] init the MyInstantiationAwareBeanPostProcessor
[postProcessBeforeInstantiation]
[Constructor] init the bean
[postProcessPropertyValues]
[setBeanName] set the bean name, value: user
[setBeanFactory] set the beanFactory, value: 
[setEnvironment] set the environment, value: 
[setEmbeddedValueResolver] set the resolver, value: 
[setResourceLoader] set the resourceLoader, value: 
[setApplicationEventPublisher] set the applicationEventPublisher, value: 
[setMessageSource] set the messageSource, value: 
[setApplicationContext] set the applicationContext, value: 
[postProcessBeforeInitialization]
[afterPropertiesSet] afterPropertiesSet.
[postConstruct] postConstruct.
[postProcessAfterInitialization]
[requiresDestruction]
context init completed
start to shutdown the context
[destroy] destroy.
[preDestroy] preDestroy.

結果分析:

  • BeanFactory最先完成準備, 因爲它是容器, 但是它的生命週期不是Bean的生命週期.Bean的生命週期是在Bean註冊到BeanDefinition中之後纔開始的.
  • 在初始化bean之前做了postProcessBeforeInstantiation回調通知.
  • 在調用bean的constructor進行初始化之後隨後調用了postProcessPropertyValues回調通知.
  • 在調用bean的afterPropertiesSet方法之前調用了postProcessBeforeInitialization回調通知.
  • 在調用了bean的afterPropertiesSetpostConstruct之後隨後調用了postProcessAfterInitialization回調通知.
  • 在容器開始銷燬時, 先調用了destroy方法, 隨後調用了preDestroy方法.

總結

Spring IoC中提供了兩個容器ApplicationContextBeanFactory, 他們管理者Bean的註冊, 初始化, 依賴注入, 銷燬等週期.
Bean的生命週期就是指從註冊到BeanDefinitionMap到最後的銷燬過程. 在Bean的生命中, 管理着它的容器()BeanFactory)提供了Bean的重要生命節點的回調函數.

參考

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