当前位置:   article > 正文

SpringBoot源码解读与原理分析(二十一)IOC容器的刷新(二)

SpringBoot源码解读与原理分析(二十一)IOC容器的刷新(二)


上一节,详细梳理了IOC容器刷新的前面三步,分别是初始化前的预处理、初始化BeanFactory以及BeanFactory的预处理配置。详见 SpringBoot源码解读与原理分析(二十)IOC容器的刷新(一) 。这一节继续梳理第四步和第五步(7.4-7.5)。

代码清单1AbstractApplicationContext.java

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // Prepare this context for refreshing.
        // 7.1 初始化前的预处理
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        // 7.2 获取BeanFactory,加载所有bean的定义信息(未实例化)
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        // 7.3 BeanFactory的预处理配置
        prepareBeanFactory(beanFactory);

        try {
            // Allows post-processing of the bean factory in context subclasses.
            // 7.4 BeanFactory准备工作完成后的后置处理
            postProcessBeanFactory(beanFactory);

            // Invoke factory processors registered as beans in the context.
            // 7.5 BeanFactory创建后的后置处理器的执行
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            // 7.6 注册Bean的后置处理器
            registerBeanPostProcessors(beanFactory);

            // Initialize message source for this context.
            // 7.7 初始化MessageSource
            initMessageSource();

            // Initialize event multicaster for this context.
            // 7.8 初始化事件广播器
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            // 7.9 子类的多态onRefresh
            onRefresh();

            // Check for listener beans and register them.
            // 7.10 注册监听器
            registerListeners();

            // 至此,BeanFactory创建完成

            // Instantiate all remaining (non-lazy-init) singletons.
            // 7.11 初始化所有剩下的单实例
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            // 7.12 完成容器的创建工作
            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...
            // 7.13 清理缓存
            resetCommonCaches();
        }
    }
}
  • 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
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76

7.4 BeanFactory准备工作完成后的后置处理

// Allows post-processing of the bean factory in context subclasses.
// 7.4 BeanFactory准备工作完成后的后置处理
postProcessBeanFactory(beanFactory);
  • 1
  • 2
  • 3
代码清单2AbstractApplicationContext.java

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
  • 1
  • 2
  • 3
  • 4

由 代码清单2 可知,postProcessBeanFactory是一个模板方法,需要子类重写。在默认整合WebMvc时,启用的AnnotationConfigServletWebServerApplicationContext中重写了该方法并做了三件事:回调父类ServletWebServerApplicationContext类的postProcessBeanFactory方法;组件扫描;解析手动传入的配置类。

代码清单3AnnotationConfigServletWebServerApplicationContext.java

@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 7.4.1 回调父类方法
    super.postProcessBeanFactory(beanFactory);
    // 7.4.2 组件扫描
    if (this.basePackages != null && this.basePackages.length > 0) {
        this.scanner.scan(this.basePackages);
    }
    // 7.4.2 解析手动传入的配置类
    if (!this.annotatedClasses.isEmpty()) {
        this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

7.4.1 回调父类方法

代码清单4ServletWebServerApplicationContext.java

@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 注册ServletContext回调注入器
    beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
    beanFactory.ignoreDependencyInterface(ServletContextAware.class);
    // 注册Web相关的作用域
    registerWebApplicationScopes();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

由 代码清单4 可知,回调的父类ServletWebServerApplicationContext的postProcessBeanFactory方法中注册了一个后置处理器和一组基于Web应用的作用域。

7.4.1.1 ServletContextAwareProcessor
代码清单5WebApplicationContextServletContextAwareProcessor.java

public class WebApplicationContextServletContextAwareProcessor extends ServletContextAwareProcessor {
  • 1
  • 2
  • 3

由 代码清单5 可知,WebApplicationContextServletContextAwareProcessor的父类是ServletContextAwareProcessor,ServletContext回调注入的逻辑均在父类中重写的postProcessBeforeInitialization方法中。

代码清单6ServletContextAwareProcessor.java

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    if (getServletContext() != null && bean instanceof ServletContextAware) {
        ((ServletContextAware) bean).setServletContext(getServletContext());
    }
    if (getServletConfig() != null && bean instanceof ServletConfigAware) {
        ((ServletConfigAware) bean).setServletConfig(getServletConfig());
    }
    return bean;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

由 代码清单6 可知,postProcessBeforeInitialization方法完成了ServletContext和ServletConfig的回调注入。

7.4.1.2 注册Web应用的作用域
代码清单7ServletWebServerApplicationContext.java

private void registerWebApplicationScopes() {
    ExistingWebApplicationScopes existingScopes = new ExistingWebApplicationScopes(getBeanFactory());
    WebApplicationContextUtils.registerWebApplicationScopes(getBeanFactory());
    existingScopes.restore();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

由 代码清单7 可知,这里有一个特别的类:ExistingWebApplicationScopes,由类型直译是已经存在的作用域

代码清单8ServletWebServerApplicationContext.java

public static class ExistingWebApplicationScopes {

    private static final Set<String> SCOPES;
    
    static {
        // 预初始化了两个作用域request和session
        Set<String> scopes = new LinkedHashSet<>();
        scopes.add(WebApplicationContext.SCOPE_REQUEST);
        scopes.add(WebApplicationContext.SCOPE_SESSION);
        SCOPES = Collections.unmodifiableSet(scopes);
    }
    
    private final ConfigurableListableBeanFactory beanFactory;
    
    private final Map<String, Scope> scopes = new HashMap<>();
    
    public ExistingWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) {
        this.beanFactory = beanFactory;
        for (String scopeName : SCOPES) {
            // 如果BeanFactory中存在和默认作用域一样的,则覆盖默认作用域
            Scope scope = beanFactory.getRegisteredScope(scopeName);
            if (scope != null) {
                this.scopes.put(scopeName, scope);
            }
        }
    }
    
    public void restore() {
        // 重新注册作用域
        this.scopes.forEach((key, value) -> {
            if (logger.isInfoEnabled()) {
                logger.info("Restoring user defined scope " + key);
            }
            this.beanFactory.registerScope(key, value);
        });
    }

}
  • 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

由 代码清单8 可知,ExistingWebApplicationScopes在创建时会检查BeanFactory中是否已经注册过request和session作用域,如果注册了,则保存到Map集合中。

默认情况下,项目中不会重新定义request和session作用域,因此ExistingWebApplicationScopes的构造方法不会提取到值。但如果提取到了值,说明项目中提前注册过request或session作用域,也就是项目需要重新注册WebMvc中默认的request或session作用域。

这样的设计给开发者提供了重写默认作用域的机会,其构造方法将自定义的作用域暂存起来,等默认的request和session作用域注册完毕后,再将暂存的自定义作用域重新注册到BeanFactory中。

默认的request和session作用域是在WebApplicationContextUtils.registerWebApplicationScopes(getBeanFactory());实现的:

代码清单9WebApplicationContextUtils.java

public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory) {
    registerWebApplicationScopes(beanFactory, null);
}

public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,
@Nullable ServletContext sc) {
    // 注册默认的request和session作用域
    beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
    beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());
    // ServletContext参数值是null,因此默认情况下application作用域不会注册
    if (sc != null) {
        ServletContextScope appScope = new ServletContextScope(sc);
        beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);
        // Register as ServletContext attribute, for ContextCleanupListener to detect it.
        sc.setAttribute(ServletContextScope.class.getName(), appScope);
    }
    // 依赖注入的支持
    beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
    beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
    beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
    beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
    if (jsfPresent) {
        FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
    }
}
  • 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

由 代码清单9 可知,此时只会注册request和session作用域而不会注册application作用域,因为此时嵌入式Web容器还没有初始化,ServletContext也没有创建。

7.4.2 组件扫描&解析手动传入的配置类

代码清单10AnnotationConfigServletWebServerApplicationContext.java

public class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContext
		implements AnnotationConfigRegistry {

	private final AnnotatedBeanDefinitionReader reader;
	private final ClassPathBeanDefinitionScanner scanner;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

由 代码清单10 可知,AnnotationConfigServletWebServerApplicationContext内部集成了注解类解析器AnnotatedBeanDefinitionReader和组件包扫描器ClassPathBeanDefinitionScanner,这一步的组件扫描和解析手动传入的配置类就是这两个集成的组件在工作。

7.5 BeanFactory创建后的后置处理器的执行

// Invoke factory processors registered as beans in the context.
// 7.5 BeanFactory创建后的后置处理器的执行
invokeBeanFactoryPostProcessors(beanFactory);
  • 1
  • 2
  • 3
代码清单11AbstractApplicationContext.java

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // 执行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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

由 代码清单11 可知,invokeBeanFactoryPostProcessors方法看似简单,但其中的PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors静态方法非常复杂,源码也非常长。下面将该方法的源码拆开来看。

7.5.1 分离现有(传入)的BeanFactory后置处理器

代码清单12PostProcessorRegistrationDelegate.java

public static void invokeBeanFactoryPostProcessors(
    ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

    // Invoke BeanDefinitionRegistryPostProcessors first, if any.
    Set<String> processedBeans = new HashSet<>();
    // 检查当前BeanFactory是否同时是一个BeanDefinitionRegistry
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
        // 遍历现有(传入)的BeanFactory后置处理器
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            // 如果是BeanDefinitionRegistryPostProcessor,则存入registryProcessors
            // 如果不是则存入regularPostProcessors
            // 达到分离现有的BeanFactory后置处理器的目的
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                    (BeanDefinitionRegistryPostProcessor) postProcessor;
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                registryProcessors.add(registryProcessor);
            }
            else {
                regularPostProcessors.add(postProcessor);
            }
        }
        //...
}
  • 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

由 代码清单12 可知,invokeBeanFactoryPostProcessors方法首先会检查当前BeanFactory是否同时是一个BeanDefinitionRegistry。

SpringBoot源码解读与原理分析(二十)IOC容器的刷新(一) 7.2.3 获取BeanFactory 中提到,此时BeanFactory的落地实现就是一个DefaultListableBeanFactory。而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,因此该if逻辑判断必定为true。

进入if结构后,对现有(传入)的beanFactoryPostProcessors集合进行类型分离,最终分离出两个集合registryProcessors和regularPostProcessors,分别对应存放BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor。

同时,立即执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法。

7.5.2 执行最高优先级的BeanDefinitionRegistryPostProcessor

代码清单13PostProcessorRegistrationDelegate.java

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!
    // Separate between BeanDefinitionRegistryPostProcessors that implement
    // PriorityOrdered, Ordered, and the rest.
    List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
    
    // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
    // 首先,执行实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessors
    String[] postProcessorNames =
    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            // 保存实现了PriorityOrdered接口的后置处理器
            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
            processedBeans.add(ppName);
        }
    }
    // 排序
    sortPostProcessors(currentRegistryProcessors, beanFactory);
    registryProcessors.addAll(currentRegistryProcessors);
    // 依序调用
    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    // 清掉集合,下次再使用
    currentRegistryProcessors.clear();
    //...
}
  • 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

由 代码清单13 可知,这一步首先会从BeanFactory中提取出所有的BeanDefinitionRegistryPostProcessor(上一步是从传入的集合中分离出),并逐个检查这些后置处理器是否实现了PriorityOrdered接口,如果实现了则保存到currentRegistryProcessors集合中,并在排序完成后按序依次调用其postProcessBeanDefinitionRegistry方法。

7.5.3 执行其他的BeanDefinitionRegistryPostProcessor

代码清单14PostProcessorRegistrationDelegate.java

// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 其次,执行实现了Ordered接口的BeanDefinitionRegistryPostProcessors
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);
currentRegistryProcessors.clear();

// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 最后,执行所有其他的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);
    currentRegistryProcessors.clear();
}
  • 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

由 代码清单14 可知,接下来执行实现了Ordered接口的BeanDefinitionRegistryPostProcessor,执行逻辑与前一阶段几乎一致。唯一不一样的是在if判断里多了一个条件:!processedBeans.contains(ppName),这是因为BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry方法只允许执行一次,前面已经执行过的BeanDefinitionRegistryPostProcessors都会保存到processedBeans集合里,后面则需要排除已经执行过的。

最后执行的是所有其他的BeanDefinitionRegistryPostProcessors,这也有一点不一样:多了一个while循环。这样做的目的在于:BeanDefinitionRegistryPostProcessor的作用是向BeanDefinitionRegistry中注册新的BeanDefinition,如果这个新的BeanDefinition恰好又是一个BeanDefinitionRegistryPostProcessor,那么这个新的BeanDefinitionRegistryPostProcessor也需要执行其postProcessBeanDefinitionRegistry方法。因此该while循环的作用就是穷尽当前项目中会注册的所有BeanDefinitionRegistryPostProcessor,并执行postProcessBeanDefinitionRegistry方法。

7.5.4 回调postProcessBeanFactory方法

代码清单15PostProcessorRegistrationDelegate.java
    
    // ...
    // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
    // 先回调BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
    invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
    // 再调用编程式注入的BeanFactoryPostProcessor的postProcessBeanFactory方法
    invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
// 如果BeanFactory没有实现BeanDefinitionRegistry接口
else {
    // Invoke factory processors registered with the context instance.
    // 则仅调用编程式注入的BeanFactoryPostProcessor的postProcessBeanFactory方法
    invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
//...
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

由 代码清单15 可知,所有的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法执行完毕后,还要执行它们的postProcessBeanFactory方法。先回调BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法,再回调BeanFactoryPostProcessor的postProcessBeanFactory方法。

如果当前BeanFactory没有实现BeanDefinitionRegistry接口,则不需要处理以上关于BeanDefinitionRegistryPostProcessor的操作,仅调用编程式注入的BeanFactoryPostProcessor的postProcessBeanFactory方法。

7.5.5 BeanFactoryPostProcessor的分类

代码清单16PostProcessorRegistrationDelegate.java
    
// ...
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// 提取当前BeanFactory中所有的BeanFactoryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 根据是否实现PriorityOrdered、Ordered接口,将BeanFactoryPostProcessors分离为三个集合
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
        // 已经处理过的BeanFactoryPostProcessor跳过
    }
    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);
    }
}
//...
  • 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

由 代码清单16 可知,处理完所有的BeanDefinitionRegistryPostProcessor之后,开始处理BeanFactoryPostProcessor:提取出当前BeanFactory中所有的BeanFactoryPostProcessor,并根据是否实现PriorityOrdered、Ordered接口,将BeanFactoryPostProcessors分离为三个集合。

7.5.6 执行BeanFactoryPostProcessor

代码清单17PostProcessorRegistrationDelegate.java
    
// ...
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
// 首先,执行实现了PriorityOrdered接口的BeanFactoryPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
// 其次,执行实现了Ordered接口的BeanFactoryPostProcessor
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.
// 最后,执行普通的BeanFactoryPostProcessor
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();
  • 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

由 代码清单17 可知,分离出BeanFactoryPostProcessor的三个集合,按照实现了PriorityOrdered接口、Ordered接口、普通BeanFactoryPostProcessor的顺序执行其postProcessBeanFactory方法。

注意,BeanFactoryPostProcessor只有对BeanDefinition的修改、移除能力,而不能注册新的BeanDefinition,因此这里不需要while循环。也正是因为这个机制,在BeanFactoryPostProcessor执行期间,最好不要注册新的BeanDefinition,否则会因为没有while循环机制而失效。

到这,整个后置处理器的执行流程全部结束,整体流程如下:

  1. 回调编程式注入的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
  2. 回调实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
  3. 回调实现了Ordered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
  4. 回调普通的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
  5. 回调所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
  6. 回调编程式注入的BeanFactoryPostProcessor的postProcessBeanFactory方法
  7. 回调实现了PriorityOrdered接口的BeanFactoryPostProcessor的postProcessBeanFactory方法
  8. 回调实现了Ordered接口的BeanFactoryPostProcessor的postProcessBeanFactory方法
  9. 回调普通的BeanFactoryPostProcessor的postProcessBeanFactory方法

至此,IOC容器的刷新完成了第四步和第五步,分别是BeanFactory准备工作完成后进行的后置处理、BeanFactory创建后的后置处理器的执行。

本节完,更多内容请查阅分类专栏:SpringBoot源码解读与原理分析

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/63836
推荐阅读
相关标签
  

闽ICP备14008679号