Hexo

点滴积累 豁达处之

0%

ioc--后置处理器总结

生命周期的九大后置处理器

第一次调用后置处理器

源码处

1
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation

后置处理器

1
InstantiationAwareBeanPostProcessor --> postProcessBeforeInstantiation

说明

当一个bean在实例化之前,判断这个bean要不要产生一些新的对象,InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法可以返回任何类型,如果返回的对象不为null,就调用beanPostProcessor的postProcessAfterInitialization方法;后面的初始化、属性注入、实例化等方法都不会再调用
如果返回null,就正常的执行流程

注:在spring AOP当中,spring如果判断当前类100%不需要进行增强(判断当前bean是否是advice、pointcut、advisor、aopInfrastructureBean的子类,如果是,无需增强),会把这个bean放到一个map中,并将value置为false,那么在后面进行增强的时候,会排除这个map中的bean

第二次调用后置处理器

源码处

1
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#determineConstructorsFromBeanPostProcessors

后置处理器

1
SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors

说明

  • 构造器的选择主要是从determineCandidateConstructors代码中候选构造器主要从
1
Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);

后面开始的

  • 获取到所有的带@Autowired注解的构造函数,如果有一个@Autowired注解的required属性为true,那么就不能再有带@Autowired注解(不管required属性是true还是false)的构造函数,否则会报错
  • 带有@Autowire(required=false)的构造函数可以有多个

最后候选构造返回的逻辑如下

  • 如果有@Autowired的构造函数,那么不需要将无参构造加入候选列表,并返回
  • 如果@Autowired的required属性都为false,需将无参构造加入候选列表,并返回
  • 如果没有@Autowired注解的构造函数,只有一个有参构造,那么将该构造函数返回
1
2
3
4
// 2.4 如果构造函数只有一个,且有参数,那么将该构造函数赋给candidateConstructors
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
  • 不满足上述条件的候选构造参数为0,最终会用无参构造实例化,当然如下的判断与kotlin相关,在此先忽略
1
2
3
4
5
6
7
else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
}
else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
candidateConstructors = new Constructor<?>[] {primaryConstructor};
}

在第二次调用后置处理器的时候,会返回当前可用的构造函数,由此来决定,使用哪个构造函数来创建bean

第三次调用后置处理器

源码处

1
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors

后置处理器

1
MergedBeanDefinitionPostProcessor  --> postProcessMergedBeanDefinition

说明

  • AutowiredAnnotationBeanPostProcessor会扫描Bean的类中是否使用了@Autowired@Value注解,扫描到的对象会封装成一个InjectionMetadata对象,缓存到一个Map集合中,后续根据缓存信息进行属性填充;
  • CommonAnnotationBeanPostProcessor则会扫描Bean类中是否使用了@Resource等注解,同样缓存起来等待后

第四次调用后置处理器

源码处

1
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#getEarlyBeanReference

后置处理器

1
SmartInstantiationAwareBeanPostProcessor --> getEarlyBeanReference

说明

这里通过后置处理器,暴露出一个ObjectFactory(有的时候我们要的不是这个 bean 本身,而可能是经过某种处理的)

第五次调用后置处理器

源码处

1
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

后置处理器

1
InstantiationAwareBeanPostProcessor--postProcessAfterInstantiation

说明

调用的是InstantiationAwareBeanPostProcessor –> postProcessAfterInstantiation 第五个后置处理器(判断是否需要填充属性)
如果我们需要在程序中自己注入属性,可以利用这个点,在这里返回false,那么spring就不会调用下面这个后置处理器来注入属性

第六次调用后置处理器

源码处

1
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

后置处理器

1
InstantiationAwareBeanPostProcessor--postProcessPropertyValues

说明

在配置的BeanDefinition的propertyValues被设置到bean实例中之前,我们有机会拦截属性,并更改属性。

第七次调用后置处理器

源码处

1
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

后置处理器

1
BeanPostProcessor --> postProcessBeforeInitialization

说明

后置处理器,起作用的, 有以下几个:

  1. ApplicationContextAwareProcessor - 处理几个 Aware

  2. ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor - 处理 ImportAware

  3. CommonAnnotationBeanPostProcessor - 调用 @PostConstructor 对于方法集

第八次调用后置处理器

源码处

1
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

后置处理器

1
BeanPostProcessor --> postProcessAfterInitialization

说明

aop 代理的产生, 并不是全在 初始化方法之后的后置处理器中产生的.

还有一部分是在 SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference 中产生的

第九次调用后置处理器

源码处

1
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor#postProcessBeforeDestruction

后置处理器

1
DestructionAwareBeanPostProcessor -- postProcessBeforeDestruction