当我们在聊 IoC 的时候,我们来聊聊 refresh() ?(中篇)
书接上文:
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
上篇 当我们在聊 IoC 的时候,我们在聊什么?(上篇) 我们从 AnnotationConfigApplicationContext 这个类入手,对 Spring IoC 容器的整个加载过程做一个全面的剖析,本文将详细介绍这里最最核心的一个方法 refresh() 方法,这个方法是我们要重点记忆的。
在介绍 refresh() 方法之前,首先回顾一下上面的流程:
this() 方法调用无参构造函数,并且调用父类的构造方法,初始化了 BeanDefinitionReader 和 BeanDefinitionScanner 在初始化 BeanDefinitionReader 的时候 Spring 同时将 系统内置的 BeanFactoryPostProcessor 注册到了 BeanDefinition 当中(即存放到了对应的 Map)这里为之后的用户配置类的扫描和读取打下基础。register(componentClasses) 注册用户传入的配置类的 BeanDefinition 到 BeanDefinitionMap 中
那么 refresh 又做了什么?
refresh() 方法
首先一点,对于源码,我们没有必要事无巨细的扣每一行语句,除非你想改他的源码或者是其相关开发人员(这类大佬应该不用看我这篇文章了吧,挠头),否则过度的解读源码只会让你深陷其中不得要领,我们需要的是抓住其重点的方法进行解读,而边角的逻辑是需要我们进行一定的忽略的,就比如你在开发的时候通用会做很多边界值的判断以及一些异常 case 的处理,但是这些处理其实对你理解主逻辑是没有帮助的,尤其是你在不了解其内在运行机制的时候很可能就被一句边界 case 处理绕晕了。所以本文会抓住重点的方法进行罗列,而其他的分支或者低优先级的方法不会过度深究。
以上就是 refresh 中的所有调用方法,对一些方法做了简单的功能描述,这里我们重点关注其中的三个方法:
invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
finishBeanFactoryInitialization(beanFactory);
首先是 invokeBeanFactoryPostProcessors(beanFactory)
该方法初始化并调用了在上下文中注册的那些 BeanFactoryPostProcessor 这些包含了 Spring 的系统内置的后置处理器,这些后置处理器将会对我们的 Bean 进行扫描和注册。从这里也可以看出,Spring 自身的实现也是通过这些扩展点来进行的,而我们的一些插件或者开发也可以利用 Spring 提供的扩展点进行自己的定制。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
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()) 的方法,这里列出几个关键的代码,感兴趣的同学可以自行查看源码
首先是实例化并调用实现了 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor 后置处理器中的方法
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
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());
currentRegistryProcessors.clear();
然后是实现了 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();
最后调用其他的 BeanDefinitionRegistryPostProcessors
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();
}
这里是调用完了 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 方法,也就是说先调用 BeanDefinitionRegistry 的后置处理器,然后再调用 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法,也就是 BeanFactory 的后置处理器
看一眼继承关系,也就是说实现了 BeanDefinitionRegistryPostProcessor 的同时也会实现 BeanFactoryPostProcessor
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
这里调用所有上述的 registryProcessors 的 postProcessBeanFactory() 方法,以及常规的 regularPostProcessors 也就是仅实现了BeanFactoryPostProcessor 接口的类。
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
后面是获取所有实现了 BeanFactoryPostProcessor 的类并调用其后置处理方法,同样的也处理了排序的优先级
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
}
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);
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
beanFactory.clearMetadataCache();
回过头来看看,在初始化 registry 的时候注册的系统的后置处理器都做了什么:
首先是 ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
this.registriesPostProcessed.add(registryId);
processConfigBeanDefinitions(registry);
}
这个后置处理器会将我们配置带有 @Configuration 注解的类进行注册
processConfigBeanDefinitions(registry);
该方法中的 ConfigurationClassParser 将会注册我们所有带有 @Configuration 注解的类
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
parser.parse(candidates);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CFlDw7hH-1636882749426)(/Users/admin/Library/Application Support/typora-user-images/image-20211114171349566.png)]
如上图可以看到注册了我定义的 TestConfiguration 测试类
invokeBeanFactoryPostProcessors(beanFactory) 方法到此结束。
invokeBeanFactoryPostProcessors(beanFactory);
registerBeanPostProcessors(beanFactory);
finishBeanFactoryInitialization(beanFactory);
因为篇幅问题,refresh() 方法先介绍到这里,剩余的部分放到下篇。
这里是 dying 搁浅,我们下篇再见。
|