Spring进阶-BeanPostProcessor

背景

在前面的Spring进阶-Bean生命周期(上)》中提到过BeanPostProcessor,不过限于篇幅原因并没有细讲。那么什么是BeanPostProcessor?我们经常说Spring有很好的扩展性,那么这个扩展性体现在哪里呢?本文的主要内容就是来介绍什么是BeanPostProcessor。

BeanPostProcessor

废话不多说我们直接看源码,源码内容如下:

public interface BeanPostProcessor {

 @Nullable
 default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  return bean;
 }
  
 @Nullable
 default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  return bean;
 }

}

从源码可以看出,BeanPostProcessor就是一个接口而已,而它提供了两个方法。其中从名字可以看出,这两个方法调用的时机分别为Bean的初始化之前和Bean的初始化之后。现在我们知道了这个特性,那么这有什么用呢?下面我使用Spring中的一个场景来举例说明。在使用Spring时,我们可以通过ApplicationContextAwareApplicationContentx注入到我们的Bean中,例如下面的示例代码:

public class BeanPostProcessorDemo1 {
    public static void main(String[] args) {
        //创建IOC容器
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.buydeem.share.beanpostprocessor");
        //从容器中获取UserService实例
        UserService userService = context.getBean(UserService.class);
        System.out.println("userService.getApplicationContext() == context : " + (userService.getApplicationContext() == context));

    }
}

@Component
class UserService implements ApplicationContextAware {
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }
}

对于上面的的示例,最后的打印结果如下:

userService.getApplicationContext() == context : true

那么UserService示例中的ApplicationContext是如何被设置进去的呢?首先我们可以确定一定,肯定是通过ApplicationContextAware#setApplicationContext()方法设置进去的,但是谁在什么时候回调的该方法,将ApplicationContext设置进去的呢?直接看源码:

class ApplicationContextAwareProcessor implements BeanPostProcessor {

 private final ConfigurableApplicationContext applicationContext;

 private final StringValueResolver embeddedValueResolver;

 public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
  this.applicationContext = applicationContext;
  this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
 }


 @Override
 @Nullable
 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
    bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
    bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
   return bean;
  }

  AccessControlContext acc = null;

  if (System.getSecurityManager() != null) {
   acc = this.applicationContext.getBeanFactory().getAccessControlContext();
  }

  if (acc != null) {
   AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    invokeAwareInterfaces(bean);
    return null;
   }, acc);
  }
  else {
   invokeAwareInterfaces(bean);
  }

  return bean;
 }

 private void invokeAwareInterfaces(Object bean) {
  if (bean instanceof EnvironmentAware) {
   ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
  }
  if (bean instanceof EmbeddedValueResolverAware) {
   ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
  }
  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);
  }
 }

}

上面的源码中我们只需要关注两个方法即可,postProcessBeforeInitialization方法它是在初始化之前调用,该方法主要用来判断当前的Bean类型是不是XXXAware类型中的一种,如果是则调用invokeAwareInterfaces方法。而该方法则是调用XXXAware的setXXX方法,通过接口回调将XXX设置到实例中。

那从哪里佐证BeanPostProcessor中的两个接口回调方法是在实例化前后回调的呢?如果看了之前Bean生命周期的朋友可能有印象,Bean初始化方法的源码如下:

 protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
  if (System.getSecurityManager() != null) {
   AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    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;
 }

该方法中分别有两个方法为:applyBeanPostProcessorsBeforeInitialization和applyBeanPostProcessorsAfterInitialization,这个两个方法就是BeanPostProcessor的回调之处。它们的源码如下:

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

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

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

  Object result = existingBean;
  for (BeanPostProcessor processor : getBeanPostProcessors()) {
   Object current = processor.postProcessAfterInitialization(result, beanName);
   if (current == null) {
    return result;
   }
   result = current;
  }
  return result;
 }

如何注册BeanPostProcessor

前面我们讲了使用ApplicationContextAwareProcessor作为示例介绍了BeanPostProcessor的作用,那么它是如何被注册到容器中的呢?在AbstractApplicationContext#prepareBeanFactory源码中可以看到下面这行代码:

beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

从源码可以知道,它是通过addBeanPostProcessor注册到容器中的。如果对于之前《Spring进阶-BeanFactory》有印象的同学知道,这个方法是由ConfigurableBeanFactory接口提供的。下面我们自己使用一个示例来手动注册一个BeanPostProcessor试试。

public class BeanPostProcessorDemo2 {
    public static void main(String[] args) {
        //创建BeanFactory
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        //定义并注册BeanDefinition
        AbstractBeanDefinition bd = BeanDefinitionBuilder.genericBeanDefinition(Person.class).getBeanDefinition();
        factory.registerBeanDefinition("person",bd);
        //注册BeanPostProcessor
        factory.addBeanPostProcessor(new MyselfBeanPostProcessor());

        Person person = factory.getBean(Person.class);
    }
}

class Person implements InitializingBean {
    private String message = "默认值";

    @Override
    public void afterPropertiesSet() throws Exception {
        message = "afterPropertiesSet()修改后的值";
    }

    public String getMessage() {
        return message;
    }
}

class MyselfBeanPostProcessor implements BeanPostProcessor{
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof Person){
            String message = ((Person) bean).getMessage();
            System.out.println("postProcessBeforeInitialization : "+ message);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof Person){
            String message = ((Person) bean).getMessage();
            System.out.println("postProcessAfterInitialization : "+ message);
        }
        return bean;
    }
}

示例代码很简单,MyselfBeanPostProcessor实现BeanPostProcessor接口,它主要功能就是在初始化前后打印出Person中message的值。最后的运行结果如下:

postProcessBeforeInitialization : 默认值
postProcessAfterInitialization : afterPropertiesSet()修改后的值

其实注册BeanPostProcessor的实现也很简单,它只有一个实现,位于AbstractBeanFactory#addBeanPostProcessor中,源码如下:

 public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
  Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
  // Remove from old position, if any
  this.beanPostProcessors.remove(beanPostProcessor);
  // Track whether it is instantiation/destruction aware
  if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
   this.hasInstantiationAwareBeanPostProcessors = true;
  }
  if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
   this.hasDestructionAwareBeanPostProcessors = true;
  }
  // Add to end of list
  this.beanPostProcessors.add(beanPostProcessor);
 }

从源码可以知道,它就是通过一个List类型的变量beanPostProcessors存储了我们注册的BeanPostProcessor。

BeanPostProcessor子接口

从上面的例子我们了解了什么是BeanPostProcessor,在Spring中它还有一些子接口,这些子接口的功能与BeanPostProcessor类似,不同的在于它们的回调时机与BeanPostProcessor不同,下面的内容就是来分析这些主要的子接口。

MergedBeanDefinitionPostProcessor

Spring进阶-BeanPostProcessor
MergedBeanDefinitionPostProcessor结构

该接口分别有两个方法,其中postProcessMergedBeanDefinition是在mergeBeanDefinition之后调用,而resetBeanDefinition则是在Bean被重置的时候使用。
在Spring中我们可以通过@Autowired@Value@Inject注解来将依赖注入到Bean中,那么这个功能是如何实现的呢?对于此实现我们可以看AutowiredAnnotationBeanPostProcessor这个类。

Spring进阶-BeanPostProcessor
AutowiredAnnotationBeanPostProcessor结构

从上图可知该类实现了MergedBeanDefinitionPostProcessor接口,进而该类实现了postProcessMergedBeanDefinition方法。@Autowired等注解正是通过这个方法实现注入类型的预解析,将需要依赖注入的属性信息封装到InjectionMetadata中。而InjectionMetadata中包含了类中哪些需要注入的元素已经元素要注入到哪个目标类。有了这些信息,在Bean的生命周期属性赋值时通过InstantiationAwareBeanPostProcessor#postProcessProperties完成属性的依赖注入(注意:AutowiredAnnotationBeanPostProcessor也实现了InstantiationAwareBeanPostProcessor#postProcessProperties方法)。

  • AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
 public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    //依赖信息解析封装成InjectionMetadata
  InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
  metadata.checkConfigMembers(beanDefinition);
 }
  • AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata
  //主要是在从缓存injectionMetadataCache中获取InjectionMetadata信息,
  //还有就是判断是不是需要刷新缓存中的InjectionMetadata信息。
  //buildAutowiringMetadata才是构建InjectionMetadata主要逻辑
 private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
  String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
  InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
  if (InjectionMetadata.needsRefresh(metadata, clazz)) {
   synchronized (this.injectionMetadataCache) {
    metadata = this.injectionMetadataCache.get(cacheKey);
    if (InjectionMetadata.needsRefresh(metadata, clazz)) {
     if (metadata != null) {
      metadata.clear(pvs);
     }
     metadata = buildAutowiringMetadata(clazz);
          //将InjectionMetadata放入缓存injectionMetadataCache
     this.injectionMetadataCache.put(cacheKey, metadata);
    }
   }
  }
  return metadata;
 }
  • AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata
 private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
    //判断类中在方法、字段、类上有没有autowired注解,autowired注解默认情况Spring设置了三种
    //这三种也就是@Autowired、@Value、@Inject,可以通过AutowiredAnnotationBeanPostProcessor默认构造方法验证
  if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
   return InjectionMetadata.EMPTY;
  }

  List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
  Class<?> targetClass = clazz;

  do {
   final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
      //处理字段上的
   ReflectionUtils.doWithLocalFields(targetClass, field -> {
    MergedAnnotation<?> ann = findAutowiredAnnotation(field);
    if (ann != null) {
     if (Modifier.isStatic(field.getModifiers())) {
      if (logger.isInfoEnabled()) {
       logger.info("Autowired annotation is not supported on static fields: " + field);
      }
      return;
     }
     boolean required = determineRequiredStatus(ann);
     currElements.add(new AutowiredFieldElement(field, required));
    }
   });
      //处理方法上的
   ReflectionUtils.doWithLocalMethods(targetClass, method -> {
    Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
    if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
     return;
    }
    MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
    if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
     if (Modifier.isStatic(method.getModifiers())) {
      if (logger.isInfoEnabled()) {
       logger.info("Autowired annotation is not supported on static methods: " + method);
      }
      return;
     }
     if (method.getParameterCount() == 0) {
      if (logger.isInfoEnabled()) {
       logger.info("Autowired annotation should only be used on methods with parameters: " +
         method);
      }
     }
     boolean required = determineRequiredStatus(ann);
     PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
     currElements.add(new AutowiredMethodElement(method, required, pd));
    }
   });

   elements.addAll(0, currElements);
   targetClass = targetClass.getSuperclass();
  }
  while (targetClass != null && targetClass != Object.class);
    //构建InjectionMetadata返回
  return InjectionMetadata.forElements(elements, clazz);
 }

上面就是postProcessMergedBeanDefinition方法的整个过程,上面主要的事情就是将@Autowired等注解上的信息解析成InjectionMetadata,然后将其缓存到injectionMetadataCache中以便后面的postProcessProperties方法回调使用。

postProcessMergedBeanDefinition具体何时调用

前面我只说了MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition方法是在BeanDefinition合并之后调用,而BeanDefinition合并是在Bean实例化之前发生的,那么该方法是在实例化之前还是实例化之后呢?从源码中是可以知道,它是在实例化之后,属性赋值之前

Spring进阶-BeanPostProcessor
doCreateBean方法

从源码我们可以看出,postProcessMergedBeanDefinition的确是在实例化之后属性赋值之前。

InstantiationAwareBeanPostProcessor

在上面我们讲AutowiredAnnotationBeanPostProcessor实现时只说了解析依赖的部分,而如何注入的我们并没有说到。而它的依赖注入实现就离不开InstantiationAwareBeanPostProcessor

Spring进阶-BeanPostProcessor
InstantiationAwareBeanPostProcessor结构

从上图可以看出,该接口同样是BeanPostProcessor的子接口,它一共有三个方法(postProcessPropertyValues已过期这里就不说了)。

  • postProcessBeforeInstantiation在Bean实例化之前调用。
  • postProcessAfterInstantiation在Bean实例化之后调用。
  • postProcessProperties在属性应用前调用。
public class BeanPostProcessorDemo4 {
    public static void main(String[] args) {
        //创建BeanFactory
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        //注册InstantiationAwareBeanPostProcessor
        factory.addBeanPostProcessor(new MyInstantiationAwareBeanPostProcessor());
        //创建并注册BeanDefinition
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Student.class)
                .addPropertyValue("name", "mac")
                .addPropertyValue("classNo", "2101班")
                .getBeanDefinition()
;
        factory.registerBeanDefinition("mac",beanDefinition);
        //获取实例并打印
        Student student = factory.getBean(Student.class);
        System.out.println(student);
    }
}

class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor{
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.printf("postProcessBeforeInstantiation: beanClass = %s,beanName = %s%n",beanClass.getSimpleName(),beanName);
        return null;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        System.out.printf("postProcessAfterInstantiation: bean = %s,beanName = %s%n",bean,beanName);
        return true;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        System.out.printf("postProcessProperties: pvs = %s, bean = %s,beanName = %s%n",pvs,bean,beanName);
        return pvs;
    }
}

@Data
class Student {
    private String name;
    private String classNo;

    public Student() {
        System.out.println("无参构造方法被调用");
    }
}

上面示例的运行结果如下:

postProcessBeforeInstantiation: beanClass = Student,beanName = mac
无参构造方法被调用
postProcessAfterInstantiation: bean = Student(name=null, classNo=null),beanName = mac
postProcessProperties: pvs = PropertyValues: length=2; bean property 'name'; bean property 'classNo', bean = Student(name=null, classNo=null),beanName = mac
Student(name=mac, classNo=2101班)

从上面的运行结果可以看出,InstantiationAwareBeanPostProcessor接口回调的时机的确就是我们前面所说的。

postProcessBeforeInstantiation调用源码

查看AbstractAutowireCapableBeanFactory#createBean()方法可以找到如下内容:

Spring进阶-BeanPostProcessor
createBean方法

首先我们要确定的是doCreateBean方法里面才是Bean的实例化、属性赋值和销毁,查看标出的resolveBeforeInstantiation,它的内容如下:

 protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
  Object bean = null;
  if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
   // Make sure bean class is actually resolved at this point.
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    Class<?> targetType = determineTargetType(beanName, mbd);
    if (targetType != null) {
          //调用postProcessBeforeInstantiation
     bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
     if (bean != null) {
      bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
     }
    }
   }
   mbd.beforeInstantiationResolved = (bean != null);
  }
  return bean;
 }

而方法applyBeanPostProcessorsBeforeInstantiation内部实现如下:

 protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
  for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
   Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
   if (result != null) {
    return result;
   }
  }
  return null;
 }

上面方法就是遍历所有的InstantiationAwareBeanPostProcessor,然后逐个调用postProcessBeforeInstantiation方法。通过上述源码可知,如果这个方法返回值不为空,将直接返回结果不会进行后续Bean的实例化、属性赋值和初始化。

postProcessAfterInstantiation调用源码

对于populateBean这个方法如果看过《Spring进阶-Bean生命周期(上)》相信你一定不会陌生,这个方法就是Bean属性赋值时候的逻辑。

Spring进阶-BeanPostProcessor
populateBean属性赋值

从上面的图中我们可以看到,在属性赋值前就会调用postProcessAfterInstantiation方法,说明该方法的确是在实例化之后调用的。同时从源码可知,如果该方法返回false时,则populateBean后续的属性赋值部分代码都不会再执行,而是直接跳出populateBean方法。

postProcessProperties调用源码

同样在方法populateBean后部分有如下源码

Spring进阶-BeanPostProcessor
populateBean后部分代码

从图中可以看出,此处会调用postProcessProperties方法,并且该方法是在applyPropertyValues方法之前。通过该方法我们可以改变PropertyValues的值从而改变对Bean的属性赋值。
对于前面讲的AutowiredAnnotationBeanPostProcessor不知道你是否还有印象,前面我们已经说了postProcessMergedBeanDefinition方法将@Autowired方式的依赖注入解析出来存放在缓存中了,但是没有说是如何注入依赖的。AutowiredAnnotationBeanPostProcessorInstantiationAwareBeanPostProcessor实现类,我们通过postProcessProperties来查看它的实现。

 public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    //找到对应的InjectionMetadata信息
  InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
  try {
      //执行依赖注入
   metadata.inject(bean, beanName, pvs);
  }
  catch (BeanCreationException ex) {
   throw ex;
  }
  catch (Throwable ex) {
   throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
  }
  return pvs;
 }

通过postProcessProperties回调,AutowiredAnnotationBeanPostProcessor实现了@Autowired依赖注入。

DestructionAwareBeanPostProcessor

Spring进阶-BeanPostProcessor
DestructionAwareBeanPostProcessor结构

通过名字我们也知道这个BeanPostProcessor与Bean的销毁有关。它一共就两个方法,其中postProcessBeforeDestruction方法是在Bean销毁之前调用,而requiresDestruction则是用来判断给定的Bean实例是否需要销毁回调。下面是Bean销毁的相关代码:

 public void destroy() {
    //应用postProcessBeforeDestruction方法
  if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
   for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
    processor.postProcessBeforeDestruction(this.bean, this.beanName);
   }
  }
    //省略无关代码
    //调用DisposableBean#destroy方法
    ((DisposableBean) this.bean).destroy();
    //调用BeanDefinition中定义的destroyMethod方法
    invokeCustomDestroyMethod(this.destroyMethod);
 }

上面源码省略了很多东西,不过通过源码我们还是能很清楚的知道在何时调用的。

SmartInstantiationAwareBeanPostProcessor

该接口是InstantiationAwareBeanPostProcessor的子接口,它的UML结构如下图所示:

Spring进阶-BeanPostProcessor
SmartInstantiationAwareBeanPostProcessor结构

该接口主要提供三个方法:

  • predictBeanType:预测Bean的类型,返回第一个预测成功的Class类型,如果不能预测返回null
  • determineCandidateConstructors:选择合适的构造器,比如目标对象有多个构造器,在这里可以进行一些定制化,选择合适的构造器。
  • getEarlyBeanReference:获得提前暴露的bean引用。主要用于解决循环引用的问题。

对于SmartInstantiationAwareBeanPostProcessor而言,该接口基本上用在框架内部。对于determineCandidateConstructors方法,它的调用就在createBeanInstance内部,也就是Bean生命周期中的实例化中。而方法getEarlyBeanReference调用则在doCreateBean内部,它位于实例化(createBeanInstance)和属性赋值(populateBean)之间。

小结

通过上面内容的了解,我们明白了BeanPostProcessor的作用。简单来说,它就是在Bean的各个主要生命周期中间提交接口回调,通过接口回调执行扩展逻辑。BeanPostProcessor与Bean的生命周期密不可分,所以结合Bean的生命周期再来看BeanPostProcessor会更加清晰明了。
本文是承接之前《Spring进阶-Bean生命周期(上)》所写,所以推荐在看本文之前先阅读完前文。后续会在更新一篇《Spring进阶-Bean生命周期(下)》,将Bean生命周期和BeanPostProcessor做一个综合的讲解。


原文始发于微信公众号(一只菜鸟程序员):Spring进阶-BeanPostProcessor

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

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

(0)
小半的头像小半

相关推荐

发表回复

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