本人本科毕业,21届毕业生,一年工作经验,简历专业技能如下,现根据简历,并根据所学知识复习准备面试。

记录日期:2022.1.4

大部分知识点只做大致介绍,具体内容根据推荐博文链接进行详细复习。

框架原理 - Spring(六)之Spring IOC 源码postProcessBeanFactory()

AbstractApplicationContext#postProcessBeanFactory()

spring中并没有具体去实现postProcessBeanFactory方法,是提供给想要实现BeanPostProcessor的三方框架使用的。谁要使用谁就去实现。作用是在BeanFactory准备工作完成后做一些定制化的处理,一般结合BeanPostProcessor接口的实现类一起使用,注入一些重要资源(类似Application的属性和ServletContext的属性)。最后需要设置忽略这类BeanPostProcessor子接口的自动装配。

这里我们需要知道两个知识点BeanFactoryPostProcessor 以及 BeanPostProcessor

BeanFactoryPostProcessorBeanPostProcessor,这两个接口,都是Spring初始化bean时对外暴露的扩展功能接口:

  • BeanPostProcessor:对容器中的Bean进行后处理,对Bean进行额外的加强。
  • BeanFactoryPostProcessor:对Spring容器本身进行后处理,增强容器的功能。

后处理器接口与ApplicationContextAwareInitializingBean等接口不同,它们并非直接加在需要处理的bean类上,而是这样操作:

  1. 重新编写一个后处理器类Class,类名中最好也带上PostProcessor,好让大家知道是个后处理器的实现。
  2. 将这个类implement后处理接口(BeanPostProcessor或者BeanFactoryPostProcessor),实现其中的方法。
  3. 然后再将此类在Spring容器中注册为Bean。
  4. 当容器启动或者有bean加载时,会自动调用实现了后处理器接口的方法,将bean作为参数传入,从而实现相应的功能。

一般来说,用BeanPostProcessor比较多一些,认识Spring的后处理器也是从此开始的。

就功能而言,BeanFactoryPostProcessor的功能更加强大些,而且Spring框架本身编写了很多的实现了BeanFactoryPostProcessor接口的功能类,在spring容器启动时进行很多初始化操作。

引入:BeanPostProcessor

public interface BeanPostProcessor {
   
    // before
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
   
		return bean;
	}
    
    // after
    @Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
   
		return bean;
	}
}

对于其中的传参返回值进行解释:

  • Object bean:即将进行后处理的bean实例。
  • String beanName:bean实例的名称。
  • return Object:即bean的Object。

beforeafter 是相对bean生命周期过程中,InitializingBean<bean init="">来说的。spring会在Bean加载过程中,就是在我们的单例非懒加载的Bean进行初始化的时候,调用invokeInitMethods方法时,在之前之后会分别调用一次它的后置处理器的方法。

当每个bean加载时,spring都会调用所有实现了BeanPostProcessor接口的后处理类方法,因此要清楚几个点:

  1. 方法内一般都是先判断bean的类型,筛选出所要处理的bean之后再进行后续操作
  2. BeanPostProcessor后处理器有处理一批bean的潜力,不是只能对单个bean生效

引入:BeanFactoryPostProcessor

参考博客链接:BeanFactoryPostProcessor深度解读

容器后处理器负责处理容器本身。

作用与BeanPostProcessor差不多,运行流程也基本相同,在所有bean定义信息将要被加载,bean实例还未创建的时候,优先于BeanFactoryPostProcessor执行,利用BeanDefinitionRegistryPostProcessor给容器中再额外添加一些组件。

public interface BeanFactoryPostProcessor {
   
 
	/** * 在标准初始化之后修改应用程序上下文的内部bean工厂。 * 所有bean定义都已加载,但尚未实例化任何bean。这允许重写或添加属性,甚至可以初始化bean。 * @param beanFactory应用程序上下文使用的bean工厂 * @throws org.springframework.beans.BeansException in case of errors */
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
 
}

实现该接口,可以在spring的bean创建之前,修改bean的定义属性。也就是说,Spring允许 BeanFactoryPostProcessor 在容器实例化任何其它bean之前读取配置元数据,并可以根据需要进行修改。

例如可以把bean的scopesingleton改为prototype,也可以把property的值给修改掉。可以同时配置多个BeanFactoryPostProcessor,并通过设置order属性来控制各个BeanFactoryPostProcessor的执行次序。

引入:BeanFactoryPostProcessor子类BeanDefinitionRegistryPostProcessor

重点关注一下它的子接口BeanDefinitionRegistryPostProcessor

BeanDefinitionRegistryPostProcessorbeanFactoryPostProcessor基础上增加了postProcessBeanDefinitionRegistry()方法,用于回调传递BeanDefinitionRegistry对象,BeanDefinitionRegistry是注册bean的重要类,实现该方法可以向容器中注册bean。

postProcessBeanDefinitionRegistry()这个方法执行优先级高于postProcessBeanFactory(),具体请阅读invokeBeanFactoryPostProcessors()

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
   
	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}

它有一个重要的实现类:ConfigurationClassPostProcessor,此类非常重要,执行优先级最高,用于处理@ComponentScan@Configuration@Import等注解指定的类,从而批量注册bean,可以参考一下[Spring-BeanFactory后置处理器之ConfigurationClassPostProcessor](