详解Spring bean的生命周期

8 篇文章 0 订阅

 

Spring容器管理着bean的从创建到销毁的整个生命周期,其中经历了一个复杂的处理过程。

 

现在将整体过程分为3个大步骤:分别是实例化bean、初始化bean、销毁bean

实例化bean

1、Spring 启动的过程中实例化bean

(1)Spring的ApplicationContext初始化的时候,会初始化beanfactory。在beanfactory初始化时,会更据xml配置或者注解将bean的关键定义以<String, BeanDefinition>的map形式初始化在beanfactory中(DefaultListableBeanFactory)。其中key作为beanName.

在初始化 BeanDefinition完成后,ApplicationContext会执行一系列操作,例如调用BeanFactoryPostProcessors等等。

(2)当完成上述动作后,applicationContext会调用finishBeanFactoryInitialization(beanfactory)实例化bean。Beanfactory会遍历所有的BeanDefinitionNames,判断依赖关系,如果有依赖关系,会将依赖关系和被依赖关系的beanname用map保存起来,最后创建bean的动态代理实例。
 

2、装配bean的属性

 在完成上一步初始化了bean的BeanDefinition和相关依赖关系,并且创建了bean的动态代理后,spring会为bean装配属性,具体就是调用populateBean依次判断目标类型,为其注入相应的属性值。

/**
 * Populate the bean instance in the given BeanWrapper with the property values
 * from the bean definition.
 * @param beanName the name of the bean
 * @param mbd the bean definition for the bean
 * @param bw BeanWrapper with bean instance
 */
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
   PropertyValues pvs = mbd.getPropertyValues();

   if (bw == null) {
      if (!pvs.isEmpty()) {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
      }
      else {
         // Skip property population phase for null instance.
         return;
      }
   }

   // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
   // state of the bean before properties are set. This can be used, for example,
   // to support styles of field injection.
   boolean continueWithPropertyPopulation = true;

   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
               continueWithPropertyPopulation = false;
               break;
            }
         }
      }
   }

   if (!continueWithPropertyPopulation) {
      return;
   }

   if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
         mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

      // Add property values based on autowire by name if applicable.
      if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
         autowireByName(beanName, mbd, bw, newPvs);
      }

      // Add property values based on autowire by type if applicable.
      if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
         autowireByType(beanName, mbd, bw, newPvs);
      }

      pvs = newPvs;
   }

   boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
   boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

   if (hasInstAwareBpps || needsDepCheck) {
      PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
      if (hasInstAwareBpps) {
         for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
               InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
               pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
               if (pvs == null) {
                  return;
               }
            }
         }
      }
      if (needsDepCheck) {
         checkDependencies(beanName, mbd, filteredPds, pvs);
      }
   }

   applyPropertyValues(beanName, mbd, bw, pvs);
}

初始化bean

初始化是由调用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;
}

 

3、如果Bean实现了BeanNameAware接口的话,Spring将Bean的Id传递给setBeanName()方法

4、如果Bean实现了BeanClassLoaderAware接口的话,Spring将调用setBeanClassLoader ()方法,将ClassLoader容器实例传入

5、如果Bean实现了BeanFactoryAware接口的话,Spring将调用setBeanFactory()方法,将BeanFactory容器实例传入

上述三个步骤都是在initializeBean方法中的 调用invokeAwareMethods(beanName, bean)实现

 

6、如果Bean实现了ApplicationContextAware接口的话,Spring将调用Bean的setApplicationContext()方法,将bean所在应用上下文引用传入进来

ApplicationContextAware接口先是由applicationContext初始化beanfactory registerBeanPostProcessors将它注册成了BeanPostProcessor,然后再由第7步中的方法初始化调用了它。

 

7、如果Bean实现了BeanPostProcessor接口,Spring就将调用他们的postProcessBeforeInitialization()方法。

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
      throws BeansException {

   Object result = existingBean;
   for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
      result = beanProcessor.postProcessBeforeInitialization(result, beanName);
      if (result == null) {
         return result;
      }
   }
   return result;
}

8、如果Bean 实现了InitializingBean接口,Spring将调用他们的afterPropertiesSet()方法。类似的,如果bean使用init-method声明了初始化方法,该方法也会被调用

 

9、如果Bean 实现了BeanPostProcessor接口,Spring就将调用他们的postProcessAfterInitialization()方法。

此处与7点相互对应

 

10、这个时候bean就已经奔初始化完成在spring容器中,可以被调用了。

销毁bean

9、如果bean实现了disposablebean,spring将调用它的destory方法,如果bean使用destoryMethod声明了销毁方法,spring该方法也会销毁

示例代码:

public static void main(String[] args){
    ApplicationContext applicationContext=new   ClassPathXmlApplicationContext("application.xml");
    applicationContext.getBean(LanguageService.class).java();

}





public class LanguageServiceImpl implements LanguageService, BeanNameAware, BeanFactoryAware, ApplicationContextAware, BeanPostProcessor, InitializingBean, DisposableBean {

    public LanguageServiceImpl() {
        System.out.println(DateUtil.getCurrentData()+":执行了构造方法!");
    }

    public void setBeanName(String s) {
        System.out.println(DateUtil.getCurrentData()+":执行了setBeanName()!");
    }

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println(DateUtil.getCurrentData()+":执行了setBeanFactory()!");

    }
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println(DateUtil.getCurrentData()+":执行了setApplicationContext()!");
    }


    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(DateUtil.getCurrentData()+":执行了postProcessBeforeInitialization()!");
        return bean;
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println(DateUtil.getCurrentData()+":afterPropertiesSet()!");
    }
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(DateUtil.getCurrentData()+":postProcessAfterInitialization()!");
        return bean;
    }


    public void java() {
        System.out.println(DateUtil.getCurrentData()+":调用了实际处理方法()!");
    }

    public void destroy() throws Exception {
        System.out.println(DateUtil.getCurrentData()+":destory()!");
    }
}

执行结果

注:本文参考了书籍spring实战第4版

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值