前言
上次小编主要是分析了BeanDefiniton的创建,通过一个简单的示例,容器创建然后拿到bean实例,大家可以回顾一下:链接: Spring bean建模基础BeanDefinition-相关流程及对应的源码分析.
加下来我们着重讲一下容器的refresh()方法。因为里面方法都很重要今天就挑一个非常重要的讲一下。
refresh源码分析
AbstractApplicationContext类中的refresh
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
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();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
contextRefresh.end();
}
}
}
其中前三个方法的注释都是在为后面方法做准备,小编暂且不表,小编主要讲一下第五个方法invokeBeanFactoryPostProcessors(beanFactory);
为什么挑选这个方法,主要是放入beanDefintionMap后可以对上节课所讲的beanDefintion做出一些扩展,并且对spring的二次扩展主要也是对于这个方法,大家理解后对spring的认知扩展和面试都有一定的帮助。(主要扩展点有BeanFactoryPostProcessor,BeanPostProcessor, Listener等等)
讲这个源码之前我们先将这个方法的结论写出来,并且附上相应的测试代码来说明。
前提
- 这个方法里面执行的主要是实现了两个接口,A:BeanDefinitonRegistryPostProcessor 里面唯一方法为postProcessBeanDefinitionRegistry,B:BeanFactoryPostProcessor 里面唯一方法为postProcessBeanFactory,并且A继承了B ,为了后面更简洁的说明,小编后面将用A和B表示两个接口,并且A是B的父接口。
- A和B类的实现,交由spring容器管理,有两个方式,一种是通过注解扫描进入如:@Component,第二种是通过手工添加进容器 如:applicationContext.addBeanFactoryPostProcessor();
- 实现A和B接口同时也可能实现了两个顺序接口,PO:PriorityOrdered,O:Order,小编后面将用PO和O表示两个接口,这两个接口为标记接口没有任何方法,且PO继承了O。
invokeBeanFactoryPostProcessors流程结论
执行流程顺序,以下流程图顺序
接下来小编将代码贴上来
A接口实现并手动添加
public class AImpl implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("A---手动添加,实现子类方法");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("A---手动添加,实现父类方法");
}
}
A接口与Ordered接口实现并自动添加
@Component
public class AoImpl implements BeanDefinitionRegistryPostProcessor, Ordered {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("Ao---自动添加实现order接口,实现子类方法");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("Ao---自动添加实现order接口,实现父类方法");
}
@Override
public int getOrder() {
return 0;
}
}
A接口实现并自动添加
@Component
public class AutoAImpl implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("AutoA---自动添加,实现子类方法");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("AutoA---自动添加,实现父类方法");
}
}
B接口实现手动添加
public class BImpl implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("B---手动添加,实现父类方法");
}
}
B接口实现自动添加
@Component
public class AutoBImpl implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("B---自动添加,实现父类方法");
}
}
测试类
@ComponentScan(basePackages = "com.dtyunxi.yundt.scan")
public class PostProcessorOrderTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext();
applicationContext.addBeanFactoryPostProcessor(new AImpl());
applicationContext.addBeanFactoryPostProcessor(new BImpl());
applicationContext.register(PostProcessorOrderTest.class);
applicationContext.refresh();
}
}
执行结果
A---手动添加,实现子类方法
Ao---自动添加实现order接口,实现子类方法
AutoA---自动添加,实现子类方法
A---手动添加,实现父类方法
Ao---自动添加实现order接口,实现父类方法
AutoA---自动添加,实现父类方法
B---手动添加,实现父类方法
B---自动添加,实现父类方法
invokeBeanFactoryPostProcessors方法源码分析
这边小编开始讲述invokeBeanFactoryPostProcessors(beanFactory)源码,并附上自己的注解。希望大家能看得懂。
AbstractApplicationContext类中方法。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 实际执行交由PostProcessorRegistrationDelegate执行,大家想到是什么设计模式了吗
// 第一个参数为beanFactory
// 第二个参数为该容器中的实现BeanFacotryPostProcessor的集合类,
// 可以用上面小编所述的addBeanFactoryPostProcessor方法添加,也就是手动注入,一般情况下这个参数是个空集合
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 (!IN_NATIVE_IMAGE && 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类的名称,主要是防止重复执行,这里先添加然后执行,执行完,到下一个循环时判断实现的类是否还需要执行
Set<String> processedBeans = new HashSet<>();
// 这个是判断传入的beanFactory是否是BeanDefinitionRegistry的接口实现,
// 一般绝对会进入,除非你重写了一个自己的beanFactory,才会去执行else我们在这儿不考虑
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// regularPostProcessors 集合主要是存放自己实现BeanFactoryPostProcessor接口的类并且是手动添加
// 与下面那个集合主要就是泛型不同
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//registryProcessors 集合存放了所有实现BeanDefinitionRegistryPostProcessor接口的类包括spring内置的和程序员自己实现的
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 一般情况下没有,所以直接跳过,但是手动添加两个接口的实现类之后就可以放进去
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// 如果实现了BeanDefinitionRegistryPostProcessor接口的类,则直接执行,并且放入registryProcessors集合
// 否则就加入regularPostProcessors集合
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
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的类,执行完一次就clear一下,接着执行下一个阶段
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 首先执行的是实现BeanDefinitionRegistryPostProcessors 以及 PriorityOrdered 接口,这边会查到一个ConfigurationClassPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//加入现阶段要执行的类ConfigurationClassPostProcessor
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//已经再执行的类集合
processedBeans.add(ppName);
}
}
//排序 没关系
sortPostProcessors(currentRegistryProcessors, beanFactory);
//所有实现类的添加
registryProcessors.addAll(currentRegistryProcessors);
// ConfigurationClassPostProcessor执行,扫描注解类等然后加入beanDefintionMap
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
//现阶段执行的类清除
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 接下来执行 实现BeanDefinitionRegistryPostProcessors 以及Ordered接口的类,
// 与上面注释差不多,不过多了一个判断,即这个类是否被执行过,下面for中if的第一个判断就是
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();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 接下来执行扫描过来的实现BeanDefinitionRegistryPostProcessor的类
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();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 接下来执行BeanDefinitionRegistryPostProcessor类中父类方法,因为BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor类所以肯定是需要实现BeanFactoryPostProcessor的方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//最后是执行我们手动添加的实现BeanFactoryPostProcessor类
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
//else 不表
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
//下面的实现BeanFactoryPostProcessor接口的类执行顺序与,子接口顺序相同
// 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...
beanFactory.clearMetadataCache();
}
总结
以上是小编对于spring的refresh方法中invokeBeanFactoryPostProcessors的执行流程以及源码分析。希望小编已经让大家明白,接下来小编对今天所写内容在其他源码框架的使用和扩展。学以致用才行,加油!