1. 程式人生 > >spring原始碼分析:spring生命週期

spring原始碼分析:spring生命週期

最近在看springboot自動配置,看到了@Conditional,@ConditionalOnMissingBean等等。這些註解,一直研究他們是如何實現springboot的條件註解的。由他們回到了@Configuration,回到了ConfigurationClassPostProcessor。ConfigurationClassPostProcessor實現了BeanFactoryPostProcessor,在spring生命週期當中會存在某個地方執行實現了BeanFactoryPostProcessor的postProcessBeanFactory方法。由於以前看spring原始碼時做了比較,於是這裡再次總結一下加深自己的影響。

我會從spring生命週期分析,然後到spring如何實現註解,例如@Configuration,@Import等等,最後到@Conditional相關的註解如何實現。

先來看看spring核心程式碼:

@Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            prepareRefresh();

            // Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }

以下是我做的筆記:
這裡寫圖片描述

再來看看程式碼
App.Java

public class App {
    public static void main(String[] args) {
        System.out.println("====開始初始化容器===");

        ApplicationContext ctx = new AnnotationConfigApplicationContext(JavaConfig.class);
        System.out.println("====容器初始化成功!====");

        System.out.println("==========獲取person==============");
        Person person = (Person) ctx.getBean("person");

        person.say();
        System.out.println(person);

        System.out.println("==========獲取lazyPerson==============");
        LazyPerson lazyPerson = (LazyPerson) ctx.getBean("lazyPerson");

        System.out.println("===現在關閉容器===");

        ((ClassPathXmlApplicationContext)ctx).registerShutdownHook();
    }

}

JavaConfig

@Configuration
public class JavaConfig {


    @Bean
    @Lazy
    public LazyPerson lazyPerson(){
        return new LazyPerson();
    }

    @Bean
    public MyBeanFactoryPostProcessor myBeanFactoryPostProcessor(){
        return new MyBeanFactoryPostProcessor();
    }

    @Bean
    public MyBeanPostProcessor myBeanPostProcessor(){
        return  new MyBeanPostProcessor();
    }

    @Bean
    public MyInstantiationAwareBeanPostProcessor myInstantiationAwareBeanPostProcessor(){
        return new MyInstantiationAwareBeanPostProcessor();
    }

    @Bean
    public Person person(){
        return new Person();
    }
}

LazyPerson

public class LazyPerson {



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

MyBeanFactoryPostProcessor

public class MyBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    public MyBeanFactoryPostProcessor() {
        super();
        System.out.println("MyBeanFactoryPostProcessor=====這是BeanFactoryPostProcessor實現類構造器!!");
    }

    public void postProcessBeanFactory(ConfigurableListableBeanFactory arg0)
            throws BeansException {
        System.out
                .println("MyBeanFactoryPostProcessor=====BeanFactoryPostProcessor呼叫postProcessBeanFactory方法");
        BeanDefinition bd = arg0.getBeanDefinition("person");
        bd.getPropertyValues().addPropertyValue("phone", "110");
    }
}
 public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println("==MyBeanFactoryPostProcessor==MyBeanFactoryPostProcessor呼叫=postProcessBeanDefinitionRegistry");
    }

MyBeanPostProcessor

public class MyBeanPostProcessor implements BeanPostProcessor {

    public MyBeanPostProcessor() {
        super();
        System.out.println("MyBeanPostProcessor====這是BeanPostProcessor實現類構造器!!");
        // TODO Auto-generated constructor stub
    }

    public Object postProcessAfterInitialization(Object arg0, String arg1)
            throws BeansException {
        System.out
                .println("MyBeanPostProcessor====BeanPostProcessor介面方法postProcessAfterInitialization對屬性進行更改!");
        return arg0;
    }

    public Object postProcessBeforeInitialization(Object arg0, String arg1)
            throws BeansException {
        System.out
                .println("MyBeanPostProcessor=====BeanPostProcessor介面方法postProcessBeforeInitialization對屬性進行更改!");
        return arg0;
    }
}

MyInstantiationAwareBeanPostProcessor

public class MyInstantiationAwareBeanPostProcessor extends
        InstantiationAwareBeanPostProcessorAdapter {

    public MyInstantiationAwareBeanPostProcessor() {
        super();
        System.out
                .println("MyInstantiationAwareBeanPostProcessor=====這是InstantiationAwareBeanPostProcessorAdapter實現類構造器!!");
    }

    // 介面方法、例項化Bean之前呼叫
    @Override
    public Object postProcessBeforeInstantiation(Class beanClass,
                                                 String beanName) throws BeansException {
        System.out
                .println("MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor呼叫postProcessBeforeInstantiation方法");
        return null;
    }

    // 介面方法、例項化Bean之後呼叫
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {
        System.out
                .println("MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor呼叫postProcessAfterInitialization方法");
        return bean;
    }

    // 介面方法、設定某個屬性時呼叫
    @Override
    public PropertyValues postProcessPropertyValues(PropertyValues pvs,
                                                    PropertyDescriptor[] pds, Object bean, String beanName)
            throws BeansException {
        System.out
                .println("MyInstantiationAwareBeanPostProcessor======InstantiationAwareBeanPostProcessor呼叫postProcessPropertyValues方法");
        return pvs;
    }
}

Person

public class Person implements BeanFactoryAware, BeanNameAware,ApplicationContextAware,
        InitializingBean, DisposableBean {

    private String name;
    private String address;
    private int phone;

    private BeanFactory beanFactory;
    private String beanName;


    public Person() {
        System.out.println("【構造器】呼叫Person的構造器例項化");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("【注入屬性】注入屬性name");
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        System.out.println("【注入屬性】注入屬性address");
        this.address = address;
    }

    public int getPhone() {
        return phone;
    }

    public void setPhone(int phone) {
        System.out.println("【注入屬性】注入屬性phone");
        this.phone = phone;
    }

    public void say(){
        System.out.println("============say===============");
    }

    @Override
    public String toString() {
        return "Person [address=" + address + ", name=" + name + ", phone="
                + phone + "]";
    }

    // 這是BeanFactoryAware介面方法

    public void setBeanFactory(BeanFactory arg0) throws BeansException {
        System.out
                .println("【BeanFactoryAware介面】呼叫BeanFactoryAware.setBeanFactory()");
        this.beanFactory = arg0;
    }

    // 這是BeanNameAware介面方法
    public void setBeanName(String arg0) {
        System.out.println("【BeanNameAware介面】呼叫BeanNameAware.setBeanName()");
        this.beanName = arg0;
    }

    // 這是InitializingBean介面方法
    public void afterPropertiesSet() throws Exception {
        System.out
                .println("【InitializingBean介面】呼叫InitializingBean.afterPropertiesSet()");
    }

    // 這是DiposibleBean介面方法
    public void destroy() throws Exception {
        System.out.println("【DiposibleBean介面】呼叫DiposibleBean.destory()");
    }

    // 通過<bean>的init-method屬性指定的初始化方法
    @PostConstruct
    public void myInit() {
        System.out.println("【init-method】呼叫<bean>的init-method屬性指定的初始化方法");
    }

    // 通過<bean>的destroy-method屬性指定的初始化方法
    public void myDestory() {
        System.out.println("【destroy-method】呼叫<bean>的destroy-method屬性指定的初始化方法");
    }

    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("ApplicationContextAware===================applicationContext======================");

    }
}

我們執行App的main方法得到結果

====開始初始化容器===

**********invokeBeanFactoryPostProcessors(beanFactory)**********
MyBeanFactoryPostProcessor=====這是BeanFactoryPostProcessor實現類構造器!!
==MyBeanFactoryPostProcessor==MyBeanFactoryPostProcessor呼叫=postProcessBeanDefinitionRegistry
MyBeanFactoryPostProcessor=====BeanFactoryPostProcessor呼叫postProcessBeanFactory方法
**********invokeBeanFactoryPostProcessors(beanFactory)**********


*****registerBeanPostProcessors(beanFactory);*****
MyBeanPostProcessor====這是BeanPostProcessor實現類構造器!!
MyInstantiationAwareBeanPostProcessor=====這是InstantiationAwareBeanPostProcessorAdapter實現類構造器!!
*****registerBeanPostProcessors(beanFactory);*****


***finishBeanFactoryInitialization(beanFactory);***

*******下面的一段是因為存在其他的類存在例項化,依賴注入所有你會看到重複的兩份*****
MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor呼叫postProcessBeforeInstantiation方法
MyInstantiationAwareBeanPostProcessor======InstantiationAwareBeanPostProcessor呼叫postProcessPropertyValues方法
MyBeanPostProcessor=====BeanPostProcessor介面方法postProcessBeforeInitialization對屬性進行更改!
MyBeanPostProcessor====BeanPostProcessor介面方法postProcessAfterInitialization對屬性進行更改!
MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor呼叫postProcessAfterInitialization方法
MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor呼叫postProcessBeforeInstantiation方法
MyInstantiationAwareBeanPostProcessor======InstantiationAwareBeanPostProcessor呼叫postProcessPropertyValues方法
MyBeanPostProcessor=====BeanPostProcessor介面方法postProcessBeforeInitialization對屬性進行更改!
MyBeanPostProcessor====BeanPostProcessor介面方法postProcessAfterInitialization對屬性進行更改!
MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor呼叫postProcessAfterInitialization方法
*******上面的一段是因為存在其他的類存在例項化,依賴注入所有你會看到重複的兩份*****

MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor呼叫postProcessBeforeInstantiation方法
【構造器】呼叫Person的構造器例項化
MyInstantiationAwareBeanPostProcessor======InstantiationAwareBeanPostProcessor呼叫postProcessPropertyValues方法
【注入屬性】注入屬性phone
【BeanNameAware介面】呼叫BeanNameAware.setBeanName()
【BeanFactoryAware介面】呼叫BeanFactoryAware.setBeanFactory()
ApplicationContextAware===================applicationContext======================
MyBeanPostProcessor=====BeanPostProcessor介面方法postProcessBeforeInitialization對屬性進行更改!
【init-method】呼叫<bean>的init-method屬性指定的初始化方法
【InitializingBean介面】呼叫InitializingBean.afterPropertiesSet()
MyBeanPostProcessor====BeanPostProcessor介面方法postProcessAfterInitialization對屬性進行更改!
MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor呼叫postProcessAfterInitialization方法
***finishBeanFactoryInitialization(beanFactory);****

====容器初始化成功!====




==========獲取person==============
============say===============
Person [address=null, name=null, phone=110]
==========獲取lazyPerson==============
MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor呼叫postProcessBeforeInstantiation方法
==============LazyPerson()=========
MyInstantiationAwareBeanPostProcessor======InstantiationAwareBeanPostProcessor呼叫postProcessPropertyValues方法
MyBeanPostProcessor=====BeanPostProcessor介面方法postProcessBeforeInitialization對屬性進行更改!
========LazyPerson init====================
MyBeanPostProcessor====BeanPostProcessor介面方法postProcessAfterInitialization對屬性進行更改!
MyInstantiationAwareBeanPostProcessor=====InstantiationAwareBeanPostProcessor呼叫postProcessAfterInitialization方法
===現在關閉容器===

上面****標識的內容是我自己打上去方便你們知道refresh()哪個方法執行了什麼。我們看下我上面圖片中紅字的方法。

invokeBeanFactoryPostProcessors:
初始化BeanFactoryPostProcessor,只要是實現該介面的都會在此處初始化,MyBeanFactoryPostProcessor是實現了該介面的所以會在這裡例項化並且會呼叫它的postProcessBeanFactory方法。

registerBeanPostProcessors(beanFactory):
初始化攔截Bean的BeanPostProcessors。只要是BeanPostProcessors的子類,在初始建構函式時,都會呼叫子類的前後方法
MyBeanPostProcessor和MyInstantiationAwareBeanPostProcessor都實現了該介面,會在這裡執行它的初始化方法。

finishBeanFactoryInitialization(beanFactory):
這裡bean 如果不是抽象,不是懶載入,不是原型的就會在此處初始化。
bean在這裡執行getBean,此時會發生bean的初始化,和相應的依賴注入。
上面的結果中我註釋了,因為Spring容器中不止存在我們上面寫的那些bean還存在其他的。

這裡注入時:
構造器–>自動注入–>PostConstrut–>InitializingBean–>xml中配置init方法

從上面的結果中,我們可以總結出spring的生命週期。
1.初始化BeanFactoryPostProcessor。
2.執行BeanFactoryPostProcessor的postProcessBeanFactory。
3.初始化BeanPostProcessor。

發生getBean操作實現依賴注入:
4.執行InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
5.執行bean的建構函式
6.執行
postProcessBeforeInstantiation.postProcessPropertyValues
7.為bean注入屬性
8.執行bean實現的有關Aware介面
9.執行BeanPostProcessor.postProcessBeforeInitialization
10.接下來根據具體情況:
PostConstrut–>InitializingBean–>xml中配置init方法
11.BeanPostProcessor.postProcessAfterInitialization
12.容器執行
13.DisposableBean.destroy

圖片:
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述

知道了spring生命週期,我們對Spring容器中bean的操作就很得心應手了。很多其他框架在使用spring時也利用了這些特性。

這裡我們就對spring的生命週期就非常熟悉了,下一講就講解下,具體是哪裡的程式碼執行了這些操作。