从源码看Spring bean 生命周期

2 篇文章 0 订阅
在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));

}
      可以看到在初始化bean factory的准备环节中添加了该处理器.

  • 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;
    }

    这里一次处理了ServletContextAware和ServletConfigAware接口对应的方法. ServletContextAwareProcessor也是在AbstractApplicationContext#refresh时添加的,在prepareBeanFactory(添加ApplicationContextProcessor)后,调用了postProcessBeanFactory(beanFactory);处理processor的方法,该方法代码如下:
    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 这一个切入点。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值