spring源码分析:spring生命周期

Posted Small leaf

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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的生命周期就非常熟悉了,下一讲就讲解下,具体是哪里的代码执行了这些操作。

以上是关于spring源码分析:spring生命周期的主要内容,如果未能解决你的问题,请参考以下文章

从源码分析Spring的生命周期

Spring源码分析系列-Bean的生命周期(总结篇)

Spring源码分析系列-Bean的生命周期(总结篇)

Spring源码分析系列-Bean的生命周期(总结篇)

Spring源码分析系列-Bean的生命周期(总结篇)

Spring源码分析系列-Bean的生命周期(总结篇)