Bean的初始化流程

通過main函數啓動spring容器加載bean時,會有以下流程:

1、通過實現BeanFactoryPostProcessor並覆蓋postProcessBeanFactory()可以在spring容器初始化時拿到ConfigurableListableBeanFactory的實例,ConfigurableListableBeanFactory是所有bean的容器,也是BeanFactory的基礎實現。此處可以對ConfigurableListableBeanFactory做擴展。

2、執行當前bean的構造函數

3、實現了BeanNameAware的接口會執行setBeanName()可以拿到bean的id

4、實現了BeanFactoryAware的接口會執行setBeanFactory()可以拿到beanFactory實例

5、執行init-method即@PostConstruct

6、實現了InitializingBean的接口的會執行afterPropertiesSet(),該方法沒有參數,僅僅是作爲通知

7、繼承了InstantiationAwareBeanPostProcessorAdapter並重寫了其中的postProcessBeforeInstantiation方法則會拿到bean的Class類型實例和beanName

8、繼承了InstantiationAwareBeanPostProcessorAdapter並重寫了其中的postProcessAfterInstantiation方法則會拿到bean的實例和beanName

9、繼承了InstantiationAwareBeanPostProcessorAdapter並重寫了其中的postProcessPropertyValues方法則會拿到bean的實例、bean的名稱、屬性值、屬性描述符

10、繼承了InstantiationAwareBeanPostProcessorAdapter並重寫了其中的postProcessAfterInitialization方法則會拿到bean的實例和beanName

11、執行destroy前的回調

12、destroy之後的回調

 

一個栗子:

github:https://github.com/a422478514/java-practice/tree/master/src/main/java/com/daquan/_202007/_01/spring/beanlifecycle

MyBean:


import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.beans.PropertyDescriptor;

@Service
public class MyBean implements BeanPostProcessor, InstantiationAwareBeanPostProcessor, BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {

    @Autowired
    private MyBeanFactoryPostProcessor myBeanFactoryPostProcessor;

    public MyBean(){
        System.out.println("MyBean");
    }

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

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

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("setBeanFactory");
    }

    @Override
    public void setBeanName(String s) {
        System.out.println("setBeanName");
    }

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

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

}

MyBeanFactoryPostProcessor:

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Service;

@Service
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        System.out.println("configurableListableBeanFactory");
    }
}

MyInstantiationAwareBeanPostProcessor


import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import org.springframework.stereotype.Service;

import java.beans.PropertyDescriptor;

/**
 * 通過繼承InstantiationAwareBeanPostProcessorAdapter並覆蓋其中的方法來實現多個擴展
 */
@Service
public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
    // 接口方法、實例化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 bean;
    }

    // 接口方法、設置某個屬性時調用
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
            throws BeansException {
        System.out.println("postProcessPropertyValues");
        return pvs;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInstantiation");
        return true;
    }
}

TestMyBeanLifecycle


import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestMyBeanLifecycle {
    public static void main(String[] args) {
        System.out.println("加載spring容器");
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("application.xml");
        MyBean myBean = (MyBean) classPathXmlApplicationContext.getBean("myBean");
        //執行下優雅關機,否則bean的destroy方法不會被調用
        classPathXmlApplicationContext.registerShutdownHook();
    }
}

application.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" xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.1.xsd">


    <context:annotation-config />
    <!--自動掃描含有@Service將其注入爲bean -->
    <context:component-scan base-package="com.daquan._202007._01.spring.beanlifecycle" />
</beans>

 

運行結果:

configurableListableBeanFactory
MyBean
setBeanName
setBeanFactory
init
afterPropertiesSet
postProcessBeforeInstantiation
postProcessAfterInstantiation
postProcessPropertyValues
postProcessAfterInitialization
postProcessBeforeInstantiation
postProcessAfterInstantiation
postProcessPropertyValues
postProcessAfterInitialization
preDestroy
destroy

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