Spring源码之Bean的加载(五) populateBean 和 DisposableBean

bean 的加载(五)

前一篇文章主要讲解了创建 bean 中的 createBeanInstance 方法和实例化过程。本文继续讲解关于 bean 的加载过程中属性注入和注册 DisposableBean。

属性注入 populateBean

了解完循环依赖后,我们继续看属性填充是如何实现。

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
  if (bw == null) {
   if (mbd.hasPropertyValues()) {
    throw new BeanCreationException(
      mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
   } else {
    //没有可填充的属性
    return;
   }
  }

  //给InstantiationAwareBeanPostProcessors最后一个机会在属性设置前改变bean
  // 具体通过调用ibp.postProcessAfterInstantiation方法,如果调用返回false,表示不必继续进行依赖注入,直接返回
  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)) {
      //返回值为是否继续填充bean
      continueWithPropertyPopulation = false;
      break;
     }
    }
   }
  }
  //如果后处理器发出停止填充命令则终止后续的执行
  if (!continueWithPropertyPopulation) {
   return;
  }

  PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
  // 根据bean的依赖注入方式:即是否标注有 @Autowired 注解或 autowire=“byType/byName” 的标签
  // 会遍历bean中的属性,根据类型或名称来完成相应的注入
  int resolvedAutowireMode = mbd.getResolvedAutowireMode();
  if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
   MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
   //根据名称自动注入
   if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
    // 代码(1)
    autowireByName(beanName, mbd, bw, newPvs);
   }
   //根据类型自动注入
   if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
    // 代码(2)
    autowireByType(beanName, mbd, bw, newPvs);
   }
   pvs = newPvs;
  }
  // 容器是否注册了InstantiationAwareBeanPostProcessor
  boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
  // 是否进行依赖检查
  boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

  PropertyDescriptor[] filteredPds = null;
  if (hasInstAwareBpps) {
   if (pvs == null) {
    pvs = mbd.getPropertyValues();
   }
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
    if (bp instanceof InstantiationAwareBeanPostProcessor) {
     InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
     PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
     if (pvsToUse == null) {
      if (filteredPds == null) {
       filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
      }
      //对所有需要依赖检查的属性进行后处理
      pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
      if (pvsToUse == null) {
       return;
      }
     }
     pvs = pvsToUse;
    }
   }
  }
  // 检查是否满足相关依赖关系,对应的depends-on属性,3.0后已弃用
  if (needsDepCheck) {
   if (filteredPds == null) {
    filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
   }
   checkDependencies(beanName, mbd, filteredPds, pvs);
  }
  // 如果pvs不为空,将pvs上所有的属性填充到BeanWrapper对应的Bean实例中
  if (pvs != null) {
      //代码(3)
   applyPropertyValues(beanName, mbd, bw, pvs);
  }
}

在 populateBean 方法中处理流程大致如下:

  1. InstantiationAwareBeanPostProcessor 处理器中的 postProcessAfterInstantiation 方法的应用,可以控制程序是否继续进行属性填充
  2. 根据注入类型(byType/byName),提取依赖的 bean,并统一存入 PropertyValues 中
  3. 应用 InstantiationAwareBeanPostProcessor 处理器的 postProcessPropertyValues 方法,对属性获取完毕填充前对属性的再次处理,典型应用就是 RequiredAnnotationBeanPostProcessor 类中对属性的验证
  4. 将所有 PropertyValues 中的属性填充至 BeanWrapper 中

我们先分析一下代码(1)看一下 byName 是如何实现的。

autowireByName

protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
   //寻找bw中需要依赖注入的属性
   String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
   for (String propertyName : propertyNames) {
      //检查缓存bean中是否存在当前bean
      if (containsBean(propertyName)) {
         //递归初始化相关的bean. 代码(1)
         Object bean = getBean(propertyName);
         pvs.add(propertyName, bean);
         //注册依赖
         registerDependentBean(propertyName, beanName);
         if (logger.isTraceEnabled()) {
            logger.trace("Added autowiring by name from bean name '" + beanName +
                  "' via property '" + propertyName + "' to bean named '" + propertyName + "'");
         }
      } else {
         // 找不到则不处理
         if (logger.isTraceEnabled()) {
            logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
                  "' by name: no matching bean found");
         }
      }
   }
}

byName 的处理逻辑很简单,获取需要注入的 bean,然后递归调用 getBean 获取 bean 进行注入。

autowireByType

protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
   // 获取自定义的类型转换器
   TypeConverter converter = getCustomTypeConverter();
   if (converter == null) {
      converter = bw;
   }

   Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
   //寻找bw中需要依赖注入的属性
   String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
   for (String propertyName : propertyNames) {
      try {
         // 获取属性描述符
         PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
         //不要尝试按类型为Object类型自动装配:即使从技术上讲是不满意的,非简单的属性,也没有意义。
         if (Object.class != pd.getPropertyType()) {
            //探测指定属性的set方法
            MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
            // Do not allow eager init for type matching in case of a prioritized post-processor.
            boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
            DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
            //解析指定beanName的属性所匹配的值,并把解析到的属性名称存储在autowiredBeanNames中,当属性存在多个封装bean时
            //比如: @Autowired private List<A> aList; 就会找到所有匹配A类型的bean并将其注入
            Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
            if (autowiredArgument != null) {
               // 添加到待注入的bean列表中
               pvs.add(propertyName, autowiredArgument);
            }
            for (String autowiredBeanName : autowiredBeanNames) {
               //注册依赖
               registerDependentBean(autowiredBeanName, beanName);
               if (logger.isTraceEnabled()) {
                  logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
                        propertyName + "' to bean named '" + autowiredBeanName + "'");
               }
            }
            autowiredBeanNames.clear();
         }
      } catch (BeansException ex) {
         throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
      }
   }
}
  • 获取类型转换器,如果没有,默认为 bw
  • 获取需要注入的属性
  • 对所有属性进行遍历并开始注入, 首先排除 Object.class 类型,调用 resolveDependency() 方法进行校验获取对应的 bean
  • 放入 pvs 里面,并调用 registerDependentBean() 方法注册对应的依赖和被依赖关系

autowiredBeanNames 属性主要处理集合类型的注入方式,比如@autowired private List<A> tests,如果是非集合类型则该属性并无用处。

我们看一下重点是如何寻找类型匹配的。进入 resolveDependency 方法中。

DefaultListableBeanFactory#resolveDependency

public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
      @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter)
 throws BeansException 
{

   descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
   if (Optional.class == descriptor.getDependencyType()) {
      //Optional类注入的特殊处理
      return createOptionalDependency(descriptor, requestingBeanName);
   }
   else if (ObjectFactory.class == descriptor.getDependencyType() ||
         ObjectProvider.class == descriptor.getDependencyType()) {
      //ObjectFactory/ObjectProvider类注入的特殊处理
      return new DependencyObjectProvider(descriptor, requestingBeanName);
   }
   else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
      //javaxInjectProviderClass类注入的特殊处理
      return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
   }
   else {
      Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
            descriptor, requestingBeanName);
      if (result == null) {
         //通用处理逻辑
         result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
      }
      return result;
   }
}
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
      @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter)
 throws BeansException 
{

   InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
   try {
      Object shortcut = descriptor.resolveShortcut(this);
      if (shortcut != null) {
         return shortcut;
      }
      //从descriptor中获取属性类型
      Class<?> type = descriptor.getDependencyType();
      //用于支持注解@Value
      Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
      if (value != null) {
         if (value instanceof String) {
            String strVal = resolveEmbeddedValue((String) value);
            BeanDefinition bd = (beanName != null && containsBean(beanName) ?
                  getMergedBeanDefinition(beanName) : null);
            value = evaluateBeanDefinitionString(strVal, bd);
         }
         TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
         try {
            return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
         }
         catch (UnsupportedOperationException ex) {
            // A custom TypeConverter which does not support TypeDescriptor resolution...
            return (descriptor.getField() != null ?
                  converter.convertIfNecessary(value, type, descriptor.getField()) :
                  converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
         }
      }

      Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
      if (multipleBeans != null) {
         return multipleBeans;
      }
      //查找符合注入属性类型的bean ,这里过滤了 @Bean(autowireCandidate = false)和不符合@Qualifier("beanName")的bean
      Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
      if (matchingBeans.isEmpty()) {
         //为空说明找不到该注入类型的bean,如果注入的属性又是必须的,则抛出异常NoSuchBeanDefinitionException
         if (isRequired(descriptor)) {
            raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
         }
         return null;
      }

      String autowiredBeanName;
      Object instanceCandidate;
      //查询到多个符合注入属性类型的bean
      if (matchingBeans.size() > 1) {
         // 再次过滤找到最优的beanName,进而获取最优的用来创建实例的候选者instanceCandidate
         // 这里挑选@primary、@Priority等优先级高的bean
         autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
         if (autowiredBeanName == null) {
            // 找不到最优的beanName,注入的属性又是必须的,则抛NoUniqueBeanDefinitionException异常
            // 注入的属性非必须,未过滤前就有多个注入属性类型的bean,如果注入的属性不是集合,也抛异常
            if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
               return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
            }
            else {
               return null;
            }
         }
         // 根据beanName获取最优的用来创建属性实例的候选者instanceCandidate
         instanceCandidate = matchingBeans.get(autowiredBeanName);
      }
      else {
         //确定只有一个匹配项
         Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
         autowiredBeanName = entry.getKey();
         instanceCandidate = entry.getValue();
      }

      if (autowiredBeanNames != null) {
         autowiredBeanNames.add(autowiredBeanName);
      }
      if (instanceCandidate instanceof Class) {
         instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
      }
      Object result = instanceCandidate;
      if (result instanceof NullBean) {
         if (isRequired(descriptor)) {
            raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
         }
         result = null;
      }
      if (!ClassUtils.isAssignableValue(type, result)) {
         throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
      }
      return result;
   }
   finally {
      ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
   }
}

该方法在寻找类型的匹配执行顺序时,首先尝试使用解析器进行解析,如果没有成功解析,那么可能是使用默认的解析器没有做任何处理,或者使用了自定义解析器,但是对于集合等类型来说并不在解析范围内,所以再次对不同类型进行不同情况的处理。

applyPropertyValues

执行到这里后,已经完成了对所有注入属性的获取,但是获取到的属性都是 PropertyValues 形式,还没有应用到已经实例化的 bean 中,这一工作都是在 applyPropertyValues 中完成。

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
   if (pvs.isEmpty()) {
      return;
   }

   if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
      ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
   }

   MutablePropertyValues mpvs = null;
   List<PropertyValue> original;

   if (pvs instanceof MutablePropertyValues) {
      mpvs = (MutablePropertyValues) pvs;
      //如果mpvs中的值已经被转换为对应的类型那么可以直接设置到beanWrapper
      if (mpvs.isConverted()) {
         // Shortcut: use the pre-converted values as-is.
         try {
            bw.setPropertyValues(mpvs);
            return;
         } catch (BeansException ex) {
            throw new BeanCreationException(
                  mbd.getResourceDescription(), beanName, "Error setting property values", ex);
         }
      }
      original = mpvs.getPropertyValueList();
   } else {
      //如果pvs并不是使用MutablePropertyValues封装的类型,那么直接使用原始的属性获取方法
      original = Arrays.asList(pvs.getPropertyValues());
   }

   TypeConverter converter = getCustomTypeConverter();
   if (converter == null) {
      converter = bw;
   }
   //获取对应的解析器
   BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

   // Create a deep copy, resolving any references for values.
   List<PropertyValue> deepCopy = new ArrayList<>(original.size());
   boolean resolveNecessary = false;
   //遍历属性,将属性转换为对应属性的类型
   for (PropertyValue pv : original) {
      if (pv.isConverted()) {
         deepCopy.add(pv);
      } else {
         String propertyName = pv.getName();
         Object originalValue = pv.getValue();
         if (originalValue == AutowiredPropertyMarker.INSTANCE) {
            Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
            if (writeMethod == null) {
               throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
            }
            originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
         }
         Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
         Object convertedValue = resolvedValue;
         boolean convertible = bw.isWritableProperty(propertyName) &&
               !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
         if (convertible) {
            convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
         }
         // Possibly store converted value in merged bean definition,
         // in order to avoid re-conversion for every created bean instance.
         if (resolvedValue == originalValue) {
            if (convertible) {
               pv.setConvertedValue(convertedValue);
            }
            deepCopy.add(pv);
         } else if (convertible && originalValue instanceof TypedStringValue &&
               !((TypedStringValue) originalValue).isDynamic() &&
               !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
            pv.setConvertedValue(convertedValue);
            deepCopy.add(pv);
         } else {
            resolveNecessary = true;
            deepCopy.add(new PropertyValue(pv, convertedValue));
         }
      }
   }
   if (mpvs != null && !resolveNecessary) {
      mpvs.setConverted();
   }

   // Set our (possibly massaged) deep copy.
   try {
      bw.setPropertyValues(new MutablePropertyValues(deepCopy));
   } catch (BeansException ex) {
      throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Error setting property values", ex);
   }
}

初始化 bean

我们知道在配置 bean 的时候有一个init-method的属性,这个属性就是在 bean 实例化前调用所指定的方法,根据业务需求进行相应的实例化,我们现在还是回到 doCreateBean 中。

Spring源码之Bean的加载(五) populateBean 和 DisposableBean
initializeBean
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
   if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
         //代码(1)  激活 Aware 方法
         invokeAwareMethods(beanName, bean);
         return null;
      }, getAccessControlContext());
   } else {
      //对特殊的bean处理,Aware / BeanClassLoaderAware / BeanFactoryAware
      invokeAwareMethods(beanName, bean);
   }

   Object wrappedBean = bean;
   if (mbd == null || !mbd.isSynthetic()) {
      // 调用bean后处理器的方法
      // BeanPostProcessor 提供的方法,在bean初始化前调用,这时的 bean已完成了实例化和属性填充注入工作
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

   try {
      //激活用户自定义的init方法
      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()) {
      // 调用bean后处理器的方法
      // BeanPostProcessor 提供的方法,在bean初始化后调用,这时候的bean 已经创建完成了
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }
   return wrappedBean;
}

虽然该方法主要目的是执行我们设置的初始化方法的调用,但是除此之外还有其他必要的工作。

1.激活Aware方法

在了解原理前,我们先了解一下什么是 Aware,Spring

中提供了一些 Aware 相关接口,比如 BeanFactoryAware、ApplicationContextAware、ResourceLoaderAware、ServletContextAware 等,比如实现了 BeanFactoryAware 的接口的 bean 在初始化后,Spring 容器会注入 BeanFactory 的实例,实现了 ApplicationContextAware 接口的 bean 会被注入到 ApplicationContext 的实例等。

我们先了解一下 Aware 的使用。

  1. 定义一个普通 bean
/**
 * @author 神秘杰克
 * 公众号: Java菜鸟程序员
 * @date 2022/6/8
 * @Description
 */

public class Hello {

   public void say(){
      System.out.println("hello");
   }

}
  1. 定义 BeanFactoryAware 类型的 bean
/**
 * @author 神秘杰克
 * 公众号: Java菜鸟程序员
 * @date 2022/6/8
 * @Description
 */

public class AwareTest implements BeanFactoryAware {

   private BeanFactory beanFactory;

   //声明bean的时候Spring会自动注入BeanFactory
   @Override
   public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
      this.beanFactory = beanFactory;
   }

   public void testAware(){
      //通过beanFactory获取hello bean
      final Hello hello = (Hello) beanFactory.getBean("hello");
      hello.say();
   }

}
  1. 注册 bean
<bean id="hello" class="cn.jack.Hello"/>

<bean id="awareTest" class="cn.jack.AwareTest"/>
  1. 测试
public class Test {

   public static void main(String[] args) {
      final ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
      final AwareTest awareTest = (AwareTest) applicationContext.getBean("awareTest");
      awareTest.testAware();

   }
}
  1. 执行结果
hello

按照上面的方式我们可以获取到 Spring 中的 BeanFactory,并可以根据 BeanFactory 获取所有 bean,以及进行相关设置,其他 Aware 都大同小异。

具体我们看一下代码(1)调用的方法就可以一下看明白了。非常简单。

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) {
         ClassLoader bcl = getBeanClassLoader();
         if (bcl != null) {
            ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
         }
      }
      if (bean instanceof BeanFactoryAware) {
         ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
      }
   }
}

2. 处理器的应用

BeanPostProcessor 是 Spring 中开放式架构中必不可少的一个亮点,给了用户充足的权限去更改或者扩展 Spring,除了 BeanPostProcessor 外还有很多其他的 PostProcessor,当然大部分都是以此为基础,继承自 BeanPostProcessor。

在调用我们自定义初始化方法前后会分别调用 BeanPostProcessor 的postProcessBeforeInitializationpostProcessAfterInitialization方法,使得我们可以根据业务需求进行响应的处理。

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

   Object result = existingBean;
   // 获取所有实现了 BeanPostProcessors 接口的类,进行遍历
   for (BeanPostProcessor processor : getBeanPostProcessors()) {
      // 核心方法:postProcessBeforeInitialization
      Object current = processor.postProcessBeforeInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
      throws BeansException 
{

   Object result = existingBean;
    // 获取所有实现了 BeanPostProcessors 接口的类,进行遍历
   for (BeanPostProcessor processor : getBeanPostProcessors()) {
     // 核心方法:postProcessAfterInitialization
      Object current = processor.postProcessAfterInitialization(result, beanName);
      if (current == null) {
         return result;
      }
      result = current;
   }
   return result;
}

3. 激活自定义的init方法

初始化方法除了使用 init-method 外,还有自定义的 bean 实现 InitializingBean 接口,实现 afterPropertiesSet 方法实现自己的初始化业务逻辑。

当然,这两种都是在初始化 bean 的时候执行,实行顺序是 afterPropertiesSet 先执行,而 init-method 后执行。

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
      throws Throwable 
{

   //先检查是否为isInitializingBean,如果是的话先调用afterPropertiesSet方法
   boolean isInitializingBean = (bean instanceof InitializingBean);
   if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
      if (logger.isTraceEnabled()) {
         logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
      }
      // 调用 afterPropertiesSet  方法
      if (System.getSecurityManager() != null) {
         try {
            AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
               ((InitializingBean) bean).afterPropertiesSet();
               return null;
            }, getAccessControlContext());
         } catch (PrivilegedActionException pae) {
            throw pae.getException();
         }
      } else {
         ((InitializingBean) bean).afterPropertiesSet();
      }
   }

   if (mbd != null && bean.getClass() != NullBean.class{
      // 从RootBeanDefinition 中获取initMethod 方法名称
      String initMethodName = mbd.getInitMethodName();
      if (StringUtils.hasLength(initMethodName) &&
            !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
            !mbd.isExternallyManagedInitMethod(initMethodName)) {
         // 调用initMethod 方法
         invokeCustomInitMethod(beanName, bean, mbd);
      }
   }
}

需要注意的是,在使用了@PostConstruct 注解和实现了 InitializingBean 接口和 init-method 的时候。

执行顺序为 PostConstruct -> InitializingBean -> init-method

注册 DisposableBean

在 doCreateBean 中还有最后一步,就是注册 bean 到 disposableBeans,以便在销毁 bean 的时候 可以运行指定的相关业务。

除了我们熟知的 destroy-method 方法外,我们还可以注册后处理器DestructionAwareBeanPostProcessor来统一 bean 的销毁方法。

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
   AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
   if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
      //如果为单例
      if (mbd.isSingleton()) {
         /**
          * 注册一个DisposableBean的实现为以下三种给出的bean做所有的销毁工作:
          *     DestructionAwareBeanPostProcessor,DisposableBean,自定义destroy方法
          */

         registerDisposableBean(beanName,
               new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
      }
      else {
         //自定义scope的处理
         Scope scope = this.scopes.get(mbd.getScope());
         if (scope == null) {
            throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
         }
         scope.registerDestructionCallback(beanName,
               new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
      }
   }
}

至此,Spring bean 的加载流程就先告一段落。


原文始发于微信公众号(Java菜鸟程序员):Spring源码之Bean的加载(五) populateBean 和 DisposableBean

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/20941.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!