在Spring中,bean一般都以单例模式存在,除非我们将singleton属性设为false。 单例在多线程的环境下需要考虑线程安全的问题,对于一些公共的资源或数据应该怎么处理才能保证安全,应该在什么时机访问这些资源最恰当。 熟悉了spring bean的整个生命周期对于回答这些问题很有帮助。下面我们来看看spring 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);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
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);
}
return wrappedBean;
}
1、可以看到先调用invokeAwareMethods,具体如下:
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); } } }
可以看到依次调用了setBeanName --> setBeanClassLoader --> setBeanFactory 三个方法,用于在需要的时候设置对应值
2、
然后调用applyBeanPostProcessorsBeforeInitialization,依次执行所有bean post processors 的postProcessBeforeInitialization方法。注意:这里的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. 那么ApplicationContextProcessor是什么时候添加进来的呢,在AbstractApplicationContext#refresh的方法中,在prepareBeanFactory代码段,可以看到有如下代码:
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { beanFactory.setBeanClassLoader(getClassLoader()); beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // 配置上下文相关的回调 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); }
- 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; }
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig)); beanFactory.ignoreDependencyInterface(ServletContextAware.class); beanFactory.ignoreDependencyInterface(ServletConfigAware.class); WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext); WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig); }
由于processors是在一个ArrayList中维护,因此会按照顺序来执行,也就是说ApplicationContextProcessor和ServletContextAwareProcessor会先于其他spring后面添加或者我们自定义的处理器,因此其对应的Aware的切入点也会先于其他bean post processors先执行,因此bean的生命周期就先aware切入,然后才是其他切入点.
3、接着调用invokeInitMethods方法:也即处理InitializingBean接口中的afterPropertiesSet方法,然后调用用户自定义的初始化方法,也即通过init-method配置的方法。InitializingBean的afterPropertiesSet需要相应类实现该接口,会使对应类与Spring耦合,而通过init-method则不会.
4、最后调用applyBeanPostProcessorsAfterInitialization处理bean post processor的postProcessAfterInitialization切入点.
到此为止,spring bean就已经准备好可以使用了。
二、bean销毁
然后在bean factory关闭的时候会处理 DisposableBean对应的destroy方法和自定义的destroy(即destroy-method).
三、bean生命周期
现在我们可以得出一个bean的生命周期应该如下所述:
初始化(实例化)
--> 属性设置(自动注入属性)
--> BeanNameAware#setBeanName (--> BeanClassLoaderAware#setBeanClassLoader)
-- > BeanFactoryAware#setBeanFactory --> (EnvironmentAware, EmbeddedValueResolverAware, ResourceLoaderAware , ApplicationEventPublisherAware , MessageSourceAware)ApplicationContextAware#setApplicationContext
--> BeanPostProcessor#postProcessBeforeInitialization
--> InitializingBean#afterPropertiesSet(-->自定义初始化方法)
--> BeanPostProcessor#postProcessAfterInitialization
--> Bean可以正常使用
--> DisposableBean#destroy (-->自定义销毁方法)
其中红色的是比较常用的一些切入点组成的生命周期,另外这里主要分析ApplicationContext来作为容器时,bean的生命周期。如果是其他的BeanFactory,则没有上面生命周期流程的:ApplicationContextAware#setApplicationContext 这一个切入点。