Spring Bean的生命周期

来源:互联网 发布:灵知的太阳信仰 编辑:程序博客网 时间:2024/06/08 00:50

今天来看下spring中bean的生命周期问题:主要是对以下几篇博文的整理:在此感谢下列几位博主:
1:Spring Bean生命周期本博文给出了下面第一个生命周期执行流程图;并且其中的示例很不错;
2:Spring Bean 初始化过程本博文给出了BeanFactory的简单继承结构;
3:Spring面试题:Spring Bean 生命周期
4:从源码看Spring Bean的生命周期本博文很好的介绍了springbean的生命周期尤其是对AbstractAutowireCapableBeanFactory类初始化bean的过程和AbstractApplicationContext的refresh方法;以及相应的BeanPostProcess合适注入问题给出了展示;
5:BeanFactory和ApplicationContext的区别


首先我们来看下Spring Framework4.3.9 的Document中是如何说的;在 BeanFactory接口中有这样的描述:
这个根接口 Interface BeanFactory主要是为了访问Spring的bean 容器;它是 bean 容器一个最基本的客户端视图;该接口有持有许多bean定义的对象实现,每个都通过 string name进行唯一的标识;根据这些 bean 的定义中 scope 的范围,在spring 2.0 scope只有 singleton prototype 两个类型,在2.0以后为了更好的支持web应用增加了 request, session,global session,来确定bean的范围;
注意到,通常依赖于通过使用setter或者构造器的依赖注入(push 配置)要比传统的“pull”配置例如beanfactory查找要好的多;Spring的依赖注入功能是通过这个BeanFactory接口及其子接口实现的。
BeanFactory的实现应该尽可能支持标准的Bean生命周期接口,完整的初始化方法和它们的标准顺序如下:

  1. BeanNameAware ==> setBeanName
  2. BeanClassLoaderAware ==> setBeanClassLoade
  3. BeanFactoryAware ==> setBeanFactory
  4. EnvironmentAware ==> setEnvironment
  5. EmbeddedValueResolverAware ==> setEmbeddedValueResolver
  6. ResourceLoaderAware ==> setResourceLoader (only applicable when running in an application context)
  7. ApplicationEventPublisherAware ==> setApplicationEventPublisher (only applicable when running in an application context)
  8. MessageSourceAware ==> setMessageSource (only applicable when running in an application context)
  9. ApplicationContextAware ==> setApplicationContext (only applicable when running in an application context)
  10. ServletContextAware ==> setServletContext (only applicable when running in a web application context)
  11. BeanPostProcessors ==> postProcessBeforeInitialization
  12. InitializingBean ==> afterPropertiesSet
  13. a custom init-method definition
  14. BeanPostProcessors ==>postProcessAfterInitialization

    在关闭bean工厂时,下列生命周期方法适用:

  15. DestructionAwareBeanPostProcessors ==> postProcessBeforeDestruction

  16. DisposableBean ==> destroy
  17. a custom destroy-method definition

Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:

1、Bean自身的方法:这个包括了Bean本身调用的方法和通过配置文件中的init-method和destroy-method指定的方法

<bean id="demoBean" class="com.bean.DemoBean" init-method="initMethod">  ....... </bean> <bean id="demoBean" class="com.bean.DemoBean" destory-method="destroyMethod">  .......</bean>

2、Bean级生命周期接口方法:这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法;

3、容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。

4、工厂后处理器接口方法:这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。


执行流程图:来源于网上

这里写图片描述

这里写图片描述


了解几个关键的类:

1.AbstractApplicationContext

容器AbstractApplicationContext中有个方法是refresh()这个里面包含了整个Bean的初始化流程实现过程

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) {                // Destroy already created singletons to avoid dangling resources.                beanFactory.destroySingletons();                // Reset 'active' flag.                cancelRefresh(ex);                // Propagate exception to caller.                throw ex;            }        }    }

这里写图片描述

2. AbstractAutowireCapableBeanFactory

AbstractBeanFactory 和 AbstractAutowireCapableBeanFactory 是两个模 板抽象工厂类。AbstractBeanFactory 提供了 bean 工厂的抽象基类,同时提供 了 ConfigurableBeanFactory 的完整实现。AbstractAutowireCapableBeanFactory 是继承 了 AbstractBeanFactory 的抽象工厂,里面提供了 bean 创建的支持,包括 bean 的创建、依赖注入、检查等等功能,是一个 核心的 bean 工厂基类。
在AbstractAutowireCapableBeanFactory 的 initializeBean方法中:

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {        if (System.getSecurityManager() != null) {            AccessController.doPrivileged(new PrivilegedAction<Object>() {                @Override                public Object run() {                    invokeAwareMethods(beanName, bean);                    return null;                }            }, getAccessControlContext());        }        else {            invokeAwareMethods(beanName, bean);        }    //关键方法1 invokeAwareMethods(beanName,bean);        Object wrappedBean = bean;        if (mbd == null || !mbd.isSynthetic()) {            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);        }    //关键方法2 :applyBeanPostProcessorsBeforeInitialization        try {            invokeInitMethods(beanName, wrappedBean, mbd);        }    //关键方法3:invokeInitMethods(beanName, wrappedBean, mbd)        catch (Throwable ex) {            throw new BeanCreationException(                    (mbd != null ? mbd.getResourceDescription() : null),                    beanName, "Invocation of init method failed", ex);        }        if (mbd == null || !mbd.isSynthetic()) {            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);        }        //关键方法4:applyBeanPostProcessorsAfterInitialization        return wrappedBean;    }

上面四个方法都干了什么工作:
1.可以看到先调用invokeAwareMethods,在这个方法中依次调用了setBeanName –> setBeanClassLoader –> setBeanFactory 三个方法,用于在需要的时候设置对应值;
2.然后调用applyBeanPostProcessorsBeforeInitialization,依次执行所有BeanPostProcess 的postProcessBeforeInitialization方法。注意:这里的processors除了包括我们自定义的processors,还包括spring自身添加的processors.如:ApplicationContextAwareProcessor; ServletContextAwareProcessor;
3.接着调用invokeInitMethods方法:也即处理InitializingBean接口中的afterPropertiesSet方法,然后调用用户自定义的初始化方法,也即通过init-method配置的方法。InitializingBean的afterPropertiesSet需要相应类实现该接口,会使对应类与Spring耦合,而通过init-method则不会.
4.最后调用applyBeanPostProcessorsAfterInitialization处理bean post processor的postProcessAfterInitialization切入点.

具体源码阅读:
1.可以看到先调用invokeAwareMethods,具体如下:
可以看到依次调用了setBeanName –> setBeanClassLoader –> setBeanFactory 三个方法,用于在需要的时候设置对应值

private void invokeAwareMethods(final String beanName, final Object bean) {        if (bean instanceof Aware) {            if (bean instanceof BeanNameAware) {                ((BeanNameAware) bean).setBeanName(beanName);            }            if (bean instanceof BeanClassLoaderAware) {                ((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());            }            if (bean instanceof BeanFactoryAware) {                ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);            }        }    }

2.然后调用applyBeanPostProcessorsBeforeInitialization,依次执行所有BeanPostProcessors 的postProcessBeforeInitialization方法。
注释:由于processors是在一个ArrayList中维护,因此会按照顺序来执行,也就是说ApplicationContextProcessor和ServletContextAwareProcessor会先于其他spring后面添加或者我们自定义的处理器

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)            throws BeansException {        Object result = existingBean;        //从list中循环遍历执行beforeInitialization方法;        for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {            result = beanProcessor.postProcessBeforeInitialization(result, beanName);            if (result == null) {                return result;            }        }        return result;    }

注意:这里的processors除了包括我们自定义的processors,还包括spring自身添加的processors.
这里罗列几个和spring bean生命周期相关的processor和其添加时机.
ApplicationContextAwareProcessor:主要用于处理ApplicationContextAware接口的setApplicationContext方法,具体参见ApplicationContextAwareProcessor的postProcessBeforeInitialization方法,在该方法中,调用了ApplicationContextAwareProcessor 的 invokeAwareInterfaces方法,具体代码如下:

    private void invokeAwareInterfaces(Object bean) {        if (bean instanceof Aware) {          if (bean instanceof EnvironmentAware) {            ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());          }          if (bean instanceof EmbeddedValueResolverAware) {            ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(                new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));          }          if (bean instanceof ResourceLoaderAware) {            ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);          }          if (bean instanceof ApplicationEventPublisherAware) {            ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);          }          if (bean instanceof MessageSourceAware) {            ((MessageSourceAware) bean).setMessageSource(this.applicationContext);          }          if (bean instanceof ApplicationContextAware) {            ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);          }        }      }  

可以看到这里会依次处理EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware , ApplicationEventPublisherAware , MessageSourceAware , ApplicationContextAware.

另一个:ServletContextAwareProcessor:主要用于处理Servlet 上下文相关的信息感知.其postProcessBeforeInitialization方法具体如下:

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {        if (getServletContext() != null && bean instanceof ServletContextAware) {          ((ServletContextAware) bean).setServletContext(getServletContext());        }        if (getServletConfig() != null && bean instanceof ServletConfigAware) {          ((ServletConfigAware) bean).setServletConfig(getServletConfig());        }        return bean;      }  

3. ApplicationContext VS BeanFactory

这里写图片描述

ApplicationContext接口,它由BeanFactory接口派生而来,因而提供BeanFactory所有的功能。其次,原始的BeanFactory无法支持spring的许多插件,如AOP功能、Web应用等。所以ApplicationContext对BeanFactory做了如下扩展:
1.利用MessageSource进行国际化 ;
2.强大的事件机制(Event)
3.ResourceLoader(资源加载器)接口进行底层资源的访问
4.BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化,这样,我们就不能发现一些存在的Spring的配置问题。而ApplicationContext则相反,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误。
5.BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册