这里对应的是AbstractApplicationContext中以下部分的代码:
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
一行一行来看。
postProcessBeanFactory
这部分其实是抽象类预留的钩子接口,在run方法中用到的是如下代码(AnnotationConfigServletWebServerApplicationContext):
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.postProcessBeanFactory(beanFactory);
if (!ObjectUtils.isEmpty(this.basePackages)) {
this.scanner.scan(this.basePackages);
}
if (!this.annotatedClasses.isEmpty()) {
this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
}
}
super的代码如下(GenericWebApplicationContext):
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
if (this.servletContext != null) {
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
}
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
}
这里也是注册和忽略一些接口。
后面两行的作用,是:
- 在beanFactory中注册一些和scope相关的内容。
- 在beanFactory中,注册环境bean。
调用beanFactory的前置处理
接下来就是开一个startupStep,然后
invokeBeanFactoryPostProcessors(beanFactory);
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
这里流程里的代码也比较理解,其实就是设置了一些参数。主要来看看这个:
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
这个方法里代码比较多,分步来看:
1.如果类继承了BeanDefinitionRegistry
这里对应的代码如下:
if (beanFactory instanceof BeanDefinitionRegistry) {
//......
}
一样分步来看:
1.1 归类postProcessor
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
请注意:这里会调用registryProcessor的处理并放入registryProcessor
这里会将postProcessor归为两类:
- registryProcessor
- regularPostProcessor
这里的registryProcessor,其实是postProcessor的一个扩展,此处的注册节点是在普通的postProcessor之前的,当然也能注册一些定义postProcessor的一些bean定义。
1.2 分类并调用registryProcessor
这里会将BDRegistry分为三类:
-
PriorityOrdered, Ordered, and the rest. - 这里需要注意:注释里提到了此处并不会初始化facotryBean
1.2.1 priorityOrder
简言之,这里就是先将这些继承了priorityOrder的processor取出来,后续一次性都调用。
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
1.2.2 ordered
这里跟上面相同,就是变成了order的。
需要注意:
- 这里重新获得了一次postProcessorNames,因为在上一步可能发生了对beanFactory这部分内容的修改。
- 方法内存了processedBeans,每次初始化加入的时候判断了,这样就不会重复加入了。
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
1.2.3 other
这里就是所说的其他的了。
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}
1.3 调用所有的postProcessor
到这一步,BDRegistryProcessor都被初始化分类执行完了,接下来就是跟1.1里的regular一起处理了:
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
在这一步,registryPostProcessor就跟普通的postProcessor一样,调用其postProcessBeanFactory方法了。
2.如果不继承
按照流程,其实是我们输入的是继承了BDRegistry的,那么如果不继承呢?
其实就直接执行这个方法了:
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
也就是说:不拿这个beanFactoryPostProcessors来作为registryPostProcessor折腾了,也不管前后顺序了,直接作为postProcessor一把梭了。
3.按照优先级处理postProcessor
这里需要注意:
- 前面的所有实际上执行的postProcessor,都是传进来的参数,1里面处理的实际上都是BeanDefinitionRegistryPostProcessor。
所以接下来就是来处理beanFactory的那些postProcessor了,这部分的流程和1类似,这里只说一下不同点:
- 这里和1不同,先分类再统一执行。
- 最后会执行:beanFactory.clearMetadataCache();
注册beanFactory的前置处理
接下来就是注册了:
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
主要来看看这个:
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
这个方法里代码比较多,其实是里面干的事情总结一下就是:
-
找postProcessor:
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); -
分别处理
1.注册检查器
这里注册了一个beanPostProcessor BeanPostProcessorChecker,不知道是啥也没关系,注解写得很清楚了:这个postProcessor就是用来在beanPostProcessor实例化时,如果有bean被创建了就打印日志的。
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
2.分类postProcessor并注册
跟1的前置处理类似,这里就是按照顺序标记的进行分类,并逐一重新按顺序添加到beanFactory里面。
最后,添加了一个新的postProcesor:
new ApplicationListenerDetector(applicationContext)
这个postProcessor的目的,是检测像ApplicationListener这种内部类的。
总结
简单地说:这部分地内容就是拿着ApplicationContext里的postProcessor,对BF的处理。
到这里,我们知道了两个Spring中支持扩展的点:
- BeanDefinitionRegistryPostProcessor
- BeanPostProcessor
上面这个BeanDefinitionRegistryPostProcessor的调用,会先于postProcessor。
- 特殊处理的前提是BeanFactory继承了BeanRegistry
- 如果没有的话,上面的就不会特殊处理了,只会先一步调用。