refresh里面的invokeBeanFactoryPostProcessors方法。
这个方法干了什么呢?,执行所有实现了 BeanDefinitionRegistryPostProcessor接口的bd ,会执行所有实现了 BeanFactoryPostProcessor接口的bd。
public interface BeanFactoryPostProcessor {
/**
* 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.
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean definition registry after its
* standard initialization. All regular bean definitions will have been loaded,
* but no beans will have been instantiated yet. This allows for adding further
* bean definitions before the next post-processing phase kicks in.
* @param registry the bean definition registry used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
可以看看这两个接口,方法,参数。
ConfigurableListableBeanFactory 的一些方法之前也有讲过就不讲了
看看BeanDefinitionRegistry 能干什么,
public interface BeanDefinitionRegistry extends AliasRegistry {
/**
* 在此注册表中注册一个新的bean定义。必须支持RootBeanDefinition和ChildBeanDefinition。
* @param beanName 要注册的bean实例的名称
* @param beanDefinition 要注册的bean实例的定义
*指定的bean名称,我们不允许覆盖它
* @see GenericBeanDefinition
* @see RootBeanDefinition
* @see ChildBeanDefinition
*/
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
/**
* Remove the BeanDefinition for the given name.
* @param beanName the name of the bean instance to register
* @throws NoSuchBeanDefinitionException if there is no such bean definition
*/
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
/**
* Return the BeanDefinition for the given bean name.
* @param beanName name of the bean to find a definition for
* @return the BeanDefinition for the given name (never {@code null})
* @throws NoSuchBeanDefinitionException if there is no such bean definition
*/
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
/**
* Check if this registry contains a bean definition with the given name.
* @param beanName the name of the bean to look for
* @return if this registry contains a bean definition with the given name
*/
boolean containsBeanDefinition(String beanName);
/**
* Return the names of all beans defined in this registry.
* @return the names of all beans defined in this registry,
* or an empty array if none defined
*/
String[] getBeanDefinitionNames();
只截了一部分,可以看到BeanDefinitionRegistry主要是对bd的操作。先有这个认知再看这个方法的源码
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//1.beanFactory --获取beanFactory当中的BeanFactoryPostProcessor
//2.List<BeanFactoryPostProcessor> beanFactoryPostProcessors 存的是程序员手动通过api往spring容器当中提供得BeanFactoryPostProcessor
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()));
}
}
看注释
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
//所有已经找出来的(已经处理了,已经执行完的) BeanFactoryPostProcessor 或者 BeanDefinitionRegistryPostProcessor
//仅仅存放名字,保证不会重复执行
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//存放所有找出来的 BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//存放所有找出来的 BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
//遍历beanFactoryPostProcessors 方法传进来的一个list集合
//spring最先执行得是程序员通过api提供得 context.addBeanFactoryPostProcessor(new bfpp)
//因为这时候还没有扫描,就直接加进去了
//为什么最先执行他?为什么和扫描得执行时机不一样呢?
//一般没有元素
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//如果有的情况下首先 判断是否子类
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//如果是强转后直接执行
registryProcessor.postProcessBeanDefinitionRegistry(registry);
//执行完成后存放registryProcessors
//为什么执行完成了之后还要存放到这个list当中呢?
//主要是因为这里是判断子类,虽然子类的回调方法执行完成了
//但是父类的回调方法没有执行,存放到这个list当中就是为了
//后续到了执行父类回调的时机得时候,去遍历这个list,然后依次获取出来执行
registryProcessors.add(registryProcessor);
}
else {
//如果是父类的先不执行,先把他add到这个list当中
//意义和上面一样,主要是为了时机到了时候遍历然后执行
//既然这两个list仅仅是存放后在获取为什么需要两个呢?
//其实一个就能解决
//我的理解两个原因
//1、毕竟这是两种类一种子类一种父类,分开存放更加的合理
//2、也是最重要的原因,spring还是得区分这两种类的父类方法得执行顺序
//虽然都是执行父类的回调,但是直接实现父类的类和直接实现子类的类如果分开存放
//则可以控制这两类类的执行顺序和时机 当然这只是我的理解---不知道能不能说服你
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
//定义了一个集合来存放当前需要执行的 BeanDefinitionRegistryPostProcessor 为什么需要这个集合
//因为在spring的代码角度考虑BeanDefinitionRegistryPostProcessor的种类很多
//主要三种
//1、实现了 PriorityOrdered接口类型的
//2、实现了 Ordered 接口类型的
//3、什么都没实现
//站在BeanDefinitionRegistryPostProcessor的来源角度来考虑分为两种
//1、spring自己提供的
//2、外部提供的
//3、api提供得
//由于 BeanDefinitionRegistryPostProcessor种类很复杂,故而spring得分批执行
//这样能保证这些不同类型得BeanDefinitionRegistryPostProcessor 得执行时机
//所以每次找到合适得,就需要一个集合来存放,然后执行
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
/**
*需要执行BeanDefinitionRegistryPostProcessor 首先得实例化
*实例化之前首先spring得知道整个容器当中有哪些BeanDefinitionRegistryPostProcessor
* 容器里面有几个BeanDefinitionRegistryPostProcessor
* 执行内部的BeanDefinitionRegistryPostProcessor
* ConfigrationClassPostPorcessor#postProcessBeanDefinitionRegistry 扫描
* 实例化这个类
*/
//首先从容器(单例池或者bdmap)当中找到所有实现了 BeanDefinitionRegistryPostProcessor接口得类得名字
//从这里可知由于整个spring容器还在启动得过程中,所以这里能找到得就是spring内置得一些BeanDefinitionRegistryPostProcessor
//正常情况下 执行玩这里 这个 postProcessorNames得长度=1
//因为这里可以找到一个 属于BeanDefinitionRegistryPostProcessor类型的bd
//spring在启动的时候自己往bdMap当中添加的那个 ConfigrationClassPostPorcessor
// First, invoke the BeanDefinitionRegistryPostProcessors .
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
//根据名字去得到这个bean(实例化)
for (String ppName : postProcessorNames) {
//有没有实现PriorityOrdered接口
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//有则取,无则实例化然后put到单例池 然后在返回
//得到bean之后放到当前需要执行得list当中
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//add完成之后表示spring接下来一定会去执行他
//表示这个bean已经处理过了,下次在找到也不会添加到当前list当中
processedBeans.add(ppName);
}
}
//排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//为什么需要addAll
//添加到 registryProcessors 方便执行父类得回调
registryProcessors.addAll(currentRegistryProcessors);
//因为这个currentRegistryProcessors当中正常情况里面只有一个bean ConfigrationClassPostPorcessor
//所以这个方法的意义就是执行 ConfigrationClassPostPorcessor#postProcessBeanDefinitionRegistry
//这个方法做了很多事情
//1、完成了扫描
//完成了扫描 postProcessor.postProcessBeanDefinitionRegistry 注册bd
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//因为已经执行完了,故而需要清除这个当前list
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// getBeanNamesForType -----bean的名字
//然后再从容器当中找BeanDefinitionRegistryPostProcessor
//为什么还要找?前面不是找过了?
//原因有两个
//1、BeanDefinitionRegistryPostProcessor得主要功能就是往容器注册bd
//由于前面执行过一次,你不能保证他没有向容器当中注册一些bd,故而有可能前面那次执行
//就往容器里面注册了新的 BeanDefinitionRegistryPostProcessor 得bd 所以这里需要再找一此
//2、正如1所说得,其实第一次执行 BeanDefinitionRegistryPostProcessor 就是完成扫描
//所以有可能扫描到了程序员提供得 BeanDefinitionRegistryPostProcessor
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//找到之后首先判断是否被处理过,因为这里肯定也能找i出来第一次已经执行过的哪些 BeanDefinitionRegistryPostProcessor
//由于已经执行过的存在processedBeans这个集合,故而这里不会进if,也就是已经执行过的不会存在当前list
//然后再去判断是否 实现了Ordered接口
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);
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
//这里为是什么需要进行一个while得循环?
//执行所有没有实现PriorityOrdered 没有Ordered的BeanDefinitionRegistryPostProcessor的bean
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);
//如果能够找到一个说明可能会往容器当中添加新的bd
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
//到此为止 spring已经把容器所有得实现了 BeanDefinitionRegistryPostProcessor接口得
// 回调全部执行完了 接下来需要执行父类得
//由于前面执行得全部是子类所以必然也全部是父类
//所以前面所有执行得子类都需要再执行一边父类
//于是从registryProcessors(已经全部执行完子类回调得哪些类)遍历出来执行父类得回调
//这里执行父类的回调,但是先是执行实现了子类的bean的父类回调
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//执行直接实现了父类的回调 context.addBeanFactoryPostProcessor("父类");
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
/**
* 执行父类得回调(直接实现了父类得) 扫描得到得类
*
* beanFactory是无法注册bd进容器里的,所以不用向上面子类一样。他们所想要得到的效果是一样的,但是过程操作不同
*/
// 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<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
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<>(orderedPostProcessorNames.size());
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<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
//清除 mergedMap 清除allBeanNamesByType 缓存
//这里清除缓存主要是为了合并 --
// 因为到此为止,spring已经执行完了父类
//意味着有可能执行得哪些父类修改了bd
// 所以下次get得时候需要合并而不是直接从merged当中直接拿
beanFactory.clearMetadataCache();
}
这段代码非常长,注释也很多,仔细看,再联系我之前说的这个方法主要做的两件事。
注释写的很明白了,先执行各个BeanDefinitionRegistryPostProcessor再执行各个BeanFactoryPostProcessor。
在前面有文章写过,spring在这个方法之前会在spring里添加几个bd,而这些bd也可能实现了这两个接口,而且这两个接口还是父子接口的关系,还有就是实现BeanDefinitionRegistryPostProcessor的bd,可以重写其方法,向spring里面再注册bd,想想如果注册进来的bd又实现了这个接口,然后还有实现了这两个接口的类,又实现了PriorityOrdered或Ordered的接口,他们也会有先后顺序,所以这段代码才会写的这么复杂。
而实现BeanFactoryPostProcessor接口的类,可以做的事情就是修改spring里面的bd,所以再后面得执行beanFactory的clearMetadataCache()