Spring源码分析-BeanPostProcessor,InitializingBean的作用及执行时机

152 阅读1分钟

用途

用在bean 初始化

执行顺序

  1. BeanPostProcessor#postProcessBeforeInitialization
  2. InitializingBean->initMethod|@PostConstruct
  3. BeanPostProcessor#postProcessAfterInitialization
graph TD
BeanPostProcessor#postProcessBeforeInitialization --> InitializingBean --> BeanPostProcessor#postProcessAfterInitializatio

spring 源码

@see org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)

//@Autowired相关的属性注入已经全部完成
populateBean(beanName, mbd, instanceWrapper);
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
   invokeAwareMethods(beanName, bean);

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      //BeanPostProcessor#postProcessBeforeInitialization 初始化前
      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()) {
      //BeanPostProcessor#postProcessAfterInitialization 初始化后
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }

   return wrappedBean;
}
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
      throws Throwable {

   boolean isInitializingBean = (bean instanceof InitializingBean);
   //执行InitializingBean 实例中afterPropertiesSet 方法 
   if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
      if (logger.isTraceEnabled()) {
         logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
      }
      ((InitializingBean) bean).afterPropertiesSet();
   }

   if (mbd != null && bean.getClass() != NullBean.class) {
      String initMethodName = mbd.getInitMethodName();
      if (StringUtils.hasLength(initMethodName) &&
            !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
            !mbd.isExternallyManagedInitMethod(initMethodName)) {
         invokeCustomInitMethod(beanName, bean, mbd);
      }
   }
}