BeanFactoryPostProcessor的原理

缘起

【1】中分析了BeanPostProcessor这玩意儿. 知道了它的作用就是在bean实例化的初始化的前后搞事情. 而这里介绍的BeanFactoryPostProcessor也属于Spring提供的一个扩展点. 他能干什么呢?

分析

Spring对于BeanFactoryPostProcessor的注释也写得很详细

1
2
3
4
5
6
Modify the application context's internal bean factory after its standard
initialization. All bean definitions will have been loaded, but no beans
will have been instantiated yet. This allows for overriding or adding
properties even to eager-initializing beans.

即所有的bean定义已经保存并加载,但是没有bean被初始化,即没有任何bean实例被创建(哪怕非懒加载的bean)

关于本接口的使用,可以参见【3】,写得很详尽,例子写的也很好. 这里主要分析一下源码

首先断点打在MyBeanPostFactoryProcessor的第一行,则发现调用栈如下

AnnotationConfigApplicationContext.refresh–>refresh方法中的invokeBeanFactoryPostProcessors(beanFactory)

跟进去

org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
Instantiate and invoke all registered BeanFactoryPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before singleton instantiation.
*/
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 (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}

​ 源码1

注意,这里的ConfigurableListableBeanFactory beanFactory就是ioc容器,我们跟进源码1的第七行,我们来到org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, List)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
...
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
...

​ 源码2

可见,和【4】的源码8后面说的一段话一样,就是BeanFactoryPostProcessor也是要按照优先级排序的. 但是我们【2】中给出的例子中MyBeanPostFactoryProcessor是没有实现Ordered接口的,所以就会走第源码2的21行——即只是作为nonOrderedPostProcessors中的一元被调用. 而源码2的45行做的事情就是

org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor>, ConfigurableListableBeanFactory)

1
2
3
4
5
6
7
8
9
10
/**
* Invoke the given BeanFactoryPostProcessor beans.
*/
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

for (BeanFactoryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}

​ 源码3

即遍历所有的nonOrderedPostProcessors,调用他们的postProcessBeanFactory方法.

所以来到了我的MyBeanPostFactoryProcessor的postProcessBeanFactory方法.

而源码2的42行的nonOrderedPostProcessorNames是怎么得到的呢? 就是从源码2 的第六行得到的. 即直接从beanFactory中获取BeanFactoryPostProcessor类型的beanNames得到的(这是得到所有的BeanFactoryPostProcessor类型的beanName,后面再依据是否实现Ordered接口来分组, 这一点和BeanPostProcessor是一样的).

但是这里要多说一句,就是【2】中给的demo其实我们在MyBeanPostFactoryProcessor中是干不了什么实质性的事情的. 只能打印一下目前beanFactory中的状态. 因为创建bean实例化(也就是MainConfig中的@Bean方法)在这里的BeanFactoryPostProcessor的postProcessBeanFactory调用之后(postProcessBeanFactory方法的调用在refresh方法的invokeBeanFactoryPostProcessors,而实例化bean在refresh的finishBeanFactoryInitialization方法中执行), 要能看到 效果的话,要看【3】中的例子——使用BeanDefinitionRegistryPostProcessor 接口注册bean的定义,而不是通过 MainConfig的@Bean实例化bean. 关于BeanDefinitionRegistryPostProcessor 这个接口,我后面会再写文章说明.

关于为什么我们自定义的MyBeanPostFactoryProcessor的postProcessBeanFactory方法中能打印beanFactory中的信息非0——即已经注册了一些bean定义了. 是因为触发bean定义的注册并不只是refresh中的invokeBeanFactoryPostProcessors调用,还有refresh方法中的this()里面的”this.reader = new AnnotatedBeanDefinitionReader(this);”和register(annotatedClasses);

对于前者

我们来看看调用栈

1
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);

跟进

1
2
3
4
5
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { // AnnotationConfigApplicationContext是GenericApplicationContext的子类,后者中就有beanFactory(即ioc容器)
this();
register(annotatedClasses);
refresh();
}

跟进this()

1
2
3
4
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}

跟进第二行

1
2
3
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}

注意,registry就是AnnotationConfigApplicationContext(它也实现了BeanDefinitionRegistry接口),

跟进

1
2
3
4
5
6
7
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

上面的registry就是AnnotationConfigApplicationContext. 跟进第六行

org.springframework.context.annotation.AnnotationConfigUtils.registerAnnotationConfigProcessors(BeanDefinitionRegistry, Object)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, Object source) {

DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}

Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4);

if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}

if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}

if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}

// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}

// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}

if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}

return beanDefs;
}

​ 源码4

registry就是AnnotationConfigApplicationContext,这里的beanFactory挺有意思——它是通过第四行获取的. 而第四行的源码是

org.springframework.context.annotation.AnnotationConfigUtils.unwrapDefaultListableBeanFactory(BeanDefinitionRegistry)

1
2
3
4
5
6
7
8
9
10
11
private static DefaultListableBeanFactory unwrapDefaultListableBeanFactory(BeanDefinitionRegistry registry) {
if (registry instanceof DefaultListableBeanFactory) {
return (DefaultListableBeanFactory) registry;
}
else if (registry instanceof GenericApplicationContext) {
return ((GenericApplicationContext) registry).getDefaultListableBeanFactory();
}
else {
return null;
}
}

看到了没有? 因为传入的registry其实是AnnotationConfigApplicationContext,它并不是DefaultListableBeanFactory,而是GenericApplicationContext的子类,所以只会走第6行,而第六行就是后面说的拿beanFactory. 而beanFactory在源码4的第14行之后就不用了. 后面的就是在不断地往beanFactory的beanDefinitionNames中添加beanName(例如源码4的53行中的registerPostProcessor调用,你跟几步就会到org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(String, BeanDefinition), 而这个源码在【5】中已经谈过了——就是往beanFactory的beanDefinitionNames中添加beanName). 我们来看看添加的都是啥bean的定义,ConfigurationClassPostProcessor(对应bean的id是常量CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)、AutowiredAnnotationBeanPostProcessor(对应bean的id是AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME常量)、…. 一共7个.

而这里源码4的containsBeanDefinition调用比较有意思,它的源码实现就是通过registry(反复提到就是一个AnnotationConfigApplicationContext,即GenericApplicationContext的子类)的beanFactory的beanDefinitionMap属性(一个ConcurrentHashMap<String, BeanDefinition>(256))中是否有beanName来判断的. 而啥时候beanName会加入到这个beanDefinitionMap呢? 注意,beanDefinitionMap属性和beanDefinitionNames是平行存在于DefaultListableBeanFactory(即beanFactory)中的. 所以自然在【5】中往beanFactory的beanDefinitionNames添加beanName的时候的同时也就往beanDefinitionMap中添加beanName了. 具体代码见下

org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(String, BeanDefinition)

1
2
3
4
5
...
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);

ps: 注意,我们曾经学过的ioc容器applicationContext其实是GenericApplicationContext的子类,GenericApplicationContext类中的属性——beanFactory才是我们所谓的ioc容器(而且它在GenericApplicationContext的构造器中是直接new出来的), 注意,在【4】中其实我们也谈论了ioc容器到底是什么? 那里说的是DefaultSingletonBeanRegistry中的singletonObjects属性,这其实和这里说的是一回事情. 因为debug发现,在

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(String, ObjectFactory<?>)中的addSingleton(beanName, singletonObject);打断点,然后跟进此addSingleton方法,

1
2
3
4
5
6
7
8
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}

上面的this的实际类型就是DefaultListableBeanFactory. 也就是beanFactory. 而singletonObjects就是它的属性. 因为singletonObjects是DefaultSingletonBeanRegistry的属性,而DefaultListableBeanFactory是DefaultSingletonBeanRegistry的子类(而且DefaultListableBeanFactory也实现了BeanDefinitionRegistry接口第14行之后,而回顾【4】中搜索”org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(String, BeanDefinition)”, 我们就知道了DefaultListableBeanFactory这个beanFactory中不仅仅保持了beanDefinitionNames,而且还保持了singletonObjects(此属性在DefaultListableBeanFactory的父类DefaultSingletonBeanRegistry中),也就是beanFactory不仅仅有bean的实例列表singletonObjects——一个ConcurrentHashMap<String, Object>(256),还有bean的定义列表beanDefinitionNames——一个ArrayList(256)),beanFactory真乃全才也!!!

参考

【1】https://yfsyfs.github.io/2019/06/10/BeanPostProcessor-%E5%8E%9F%E7%90%86%E6%B5%85%E6%9E%90/

【2】https://github.com/yfsyfs/backend/tree/master/spring-annotation-beanfactorypostprocessor

【3】https://blog.csdn.net/u010316188/article/details/85782508

【4】https://yfsyfs.github.io/2019/06/13/spring-AOP-%E6%B3%A8%E8%A7%A3%E5%8E%9F%E7%90%86/

【5】https://yfsyfs.github.io/2019/06/13/Profile-%E5%8E%9F%E7%90%86/