Java-第十五部分-源码解读-后置处理器们对IOC容器和Bean的影响

366 阅读5分钟

源码解读全文

三种后置增强器

  • BeanFactoryProcessor在执行invokeBeanFactoryPostProcessors(beanFactory);,通过getBean进行创建,并根据顺序加入集合,没有保存在工厂属性中,是局部变量集合,增强完就结束使命
  • Bean后置处理器
  1. registerBeanPostProcessors(beanFactory);中通过getBean进行顺序创建
  2. getBeanNamesForType,获取BeanPostProcessor.class的所有BeanNames
  3. 依次创建,并加入集合this.beanPostProcessors.add(beanPostProcessor);

BeanPostProcessor

  • Bean功能增强,在于改变,围绕着Bean的创建和初始化过程
  • 流水线增强所有
  • 功能增强逻辑
  1. 注入了什么组件
  2. 在什么位置,用什么后置增强器,增强了什么

BeanFactoryPostProcessor

  • 后置增强工厂
  • 唯一的方法
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

InitializingBean

  • 针对单个Bean的增强
  • Bean初始化后,属性注入完之后,进行额外处理

线程池初始化之后,进行属性的显示

PostProcessorRegistrationDelegate

  • 代理执行所有的后置增强器(BeanFactoryPostProcessorBeanFactoryPostProcessor),后置增强器的管理员 image.png

BeanFactoryPostProcessor

  • 工厂创建好后进行对工厂增强,创建的是DefaultListableBeanFactory,也是一个注册中心
  • refresh()invokeBeanFactoryPostProcessors(beanFactory); 执行bean工厂的后置增强
  • 先获取this.beanFactoryPostProcessors;,工厂中有的工厂后置处理器,进行执行,一般为null

BeanDefinitionRegistryPostProcessor

  • Set<String> processedBeans保证只存在一个,拿到底层已经存在的BeanFactoryPostProcessor,并调用postProcessBeanDefinitionRegistry,先执行getBeanFactoryPostProcessors(),实际上是没有的
  • 从工厂中的BD中,根据类型获取BeanDefinitionRegistryPostProcessor.classbeanNames,并getBean,加入registryProcessors
  1. 优先处理实现了PriorityOrdered/Ordered,指定了顺序,如果都没有实现,根据类名排序
  2. 创建过程跟创建普通的Bean是一样的流程,并且此时加入了单例池中
  • invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup()); 开始执行所有当前的后置处理器的postProcessBeanDefinitionRegistry image.png
  • invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);,执行postProcessBeanFactory

方法执行过程

  • postProcessBeanDefinitionRegistry,操作BeanDefinition注册中心,自定义注册
  • postProcessBeanFactory

ConfigurationClassPostProcessor

  • 实现了PriorityOrdered会被先执行
  • 调用postProcessBeanDefinitionRegistry
  • 进行BeanDeinfition的扫描,configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));,找出配置类,加入候选集合
  • 进行配置,名称解析器
  1. ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry);
  • 解析配置类的注解信息,sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);

BeanFactoryPostProcessor

  • invokeBeanFactoryPostProcessors(beanFactory);同样是该方法内,在处理完BeanDefinitionRegistryPostProcessor之后,进行处理
  • String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);获取所有BeanFactoryPostProcessor,并创建出Bean
  • 根据PriorityOrdered/Ordered/无顺序,依次调用invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); image.png

BeanPostProcessor

  • registerBeanPostProcessors(beanFactory);
  • String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);获取所有的Bean后置处理器
  • 根据PriorityOrdered/Ordered/无顺序,依次加入集合,并依次调用
  • BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);生成Bean
  • 其中处理实现了MergedBeanDefinitionPostProcessor接口的后置处理器,internalPostProcessors.add(pp);
  • registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);,加入beanPostProcessors集合,再创建Bean的时候进行调用

同样会加入单例池中

SmartInstantiationAwareBeanPostProcessor调用

功能

  • 通过后置处理器,可以返回自定义的bean类型,在predictBeanType期间改变bean的类型
  1. 此时,后置处理器,已经形成Bean,被处理过了,不会再被处理
  2. 在其他Bean生成之前,还有机会进行类型改变
  • getBean时,用构造器创造对象之前,可以调用determineCandidateConstructors指定构造器
  • 代理增强,可以自定义返回早期Bean

第一次调用流程

  • PostProcessor处理完后,registerListeners();开始调用
  1. 事件监听机制
  • String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);,处理BeanDefinitionApplicationListener的名字

获取容器中的所有监听器的名字,为了获取监听器对象

  • doGetBeanNamesForType,通过类型,获取名字
  1. 先获取所有BD名字,beanDefinitionNames
  2. 遍历所有名字,在beanDefinitionMap找定义信息,看类型是否匹配
  3. 只保存了<name, type>的信息,没有保存<type, name[]>的信息
  • matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);

boolean allowFactoryBeanInit = (allowEagerInit || containsSingleton(beanName));,决定是否能进行类型调整,allowEagerInit默认为falsecontainsSingleton(beanName)是否已经被创建好 image.png

  • predictedType = predictBeanType(beanName, mbd, typesToMatch);,没有被提前生成Bean,会进行类型干预
  • 遍历处理,最终调用自定义的处理器,在getBeanPostProcessorCache会进行分类 image.png

第二次调用

  • finishBeanFactoryInitialization(beanFactory);String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);进行调用

加载时织入组件

InstantiationAwareBeanPostProcessor

功能

  • postProcessBeforeInstantiation自定义创建Bean

过程

  • finishBeanFactoryInitialization(beanFactory);中创建BeanbeanFactory.preInstantiateSingletons();中调用getBean
  • Object bean = resolveBeforeInstantiation(beanName, mbdToUse);,创建对象之前给后置处理器一个机会,能够提前返回一个对象,此时还没有真正创建对象 image.png

创建成功,getBean直接结束

  • 调用postProcessBeforeInstantiation image.png

MergedBeanDefinitionPostProcessor

功能

  • 修改BeanDefinition信息

过程

  • instanceWrapper = createBeanInstance(beanName, mbd, args);创建好后执行
  • applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); image.png

InstantiationAwareBeanPostProcessor

功能

  • postProcessAfterInstantiation,属性赋值之前,可以进行中断
  • postProcessProperties,进行自定义赋值,解析自定义注解

返回false,赋值过程全部结束

过程

  • populateBean(beanName, mbd, instanceWrapper);赋值时执行postProcessAfterInstantiation image.png
  • 自动注入,也在这个过程中,但是直接返回true,没做处理 image.png
  • postProcessProperties,该过程中会进行AutowiredAnnotationBeanPostProcessor自动注入
  1. @Autowired在属性上,直接复制
  2. @Autowried在方法上,调用其方法,并加入pvs中,后续调用applyPropertyValues进行属性赋值 image.png

BeanPostProcessor

功能

  • postProcessBeforeInitialization改变Bean对象

过程

  • exposedObject = initializeBean(beanName, exposedObject, mbd);赋值结束后,进行初始化
  • wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); 初始化之前的增强处理 image.png
  • invokeInitMethods之后,wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
  • 调用postProcessAfterInitialization,初始化之后进行处理 image.png

Aware

  • 其实就是BeanPostProcessor
  • initializeBean中,wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);调用初始化前的后置处理器
  • 其中会调用ApplicationContextAwareProcessorpostProcessBeforeInitialization,进行接口判断,并执行Aware接口规定的方法,invokeAwareInterfaces(bean);
  • 利用多态方式进行处理 image.png
  • 还有很多,可以自行查看invokeAwareInterfaces(bean); image.png

InitializingBean

功能

  • 自定义初始化方法,可以所有属性都准备好,初始化数据库连接池

过程

  • invokeInitMethods(beanName, wrappedBean, mbd);,执行初始化方法
  1. 可以通过beanDefinition.setInitMethodName();或者@PostConstruct自定义初始化方法
  2. invokeCustomInitMethod(beanName, bean, mbd);执行自定义初始化方法
  • 如果实现了InitializingBean,调用afterPropertiesSet image.png

对getBean影响

  • 可以通过InstantiationAwareBeanPostProcessor,自定义返回Bean
  • 在选择构造器时,可以通过SmartInstantiationAwareBeanPostProcessor自定义构造器
  • 创建Bean之后,通过MergedBeanDefinitionPostProcessor,修改BeanDefinition信息
  • 开始赋值前,通过InstantiationAwareBeanPostProcessorpostProcessAfterInstantiation,进行自定义赋值处理,可以终端初始化
  • 真正赋值时,可以通过InstantiationAwareBeanPostProcessor调用postProcessProperties,进行自定义赋值
  • 赋值结束后,在初始化之前,可以通过BeanPostProcessor,调用postProcessBeforeInitialization,改变Bean
  • 初始化过程中,可以通过实现InitializingBean接口,自定义初始化方法afterPropertiesSet
  • 在初始化之后,可以通过BeanPostProcessor,调用postProcessAfterInitialization,改变Bean