深入理解Spring容器初始化(二):BeanFactory的初始化

深入理解Spring容器初始化(二):BeanFactory的初始化前言我们知道,spring的启动其实就是容器的启动,而一般情况下,容器指的其实就是上下文ApplicationContext。AbstractApplicationContext作为整个A

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

前言

我们知道,spring 的启动其实就是容器的启动,而一般情况下,容器指的其实就是上下文 ApplicationContext

AbstractApplicationContext 作为整个 ApplicationContext 体系中最高级的抽象类,为除了 ComplexWebApplicationContextSimpleWebApplicationContext 这两个容器外的全部容器,规定好了 refresh 的整体流程,所有的容器在完成一些自己的初始化配置后,都需要调用该 refresh 方法,依次完成指定内容的初始化。

也就是说,读懂了 AbstractApplicationContext.refresh() 方法,其实就读懂了容器的启动流程:

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {

        // ================= 一、上下文的初始化 =================
        // 准备上下文
        prepareRefresh();
        // 通知子类刷新内部工厂
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
        // 准备bean工厂以便在当前上下文中使用
        prepareBeanFactory(beanFactory);

        try {
            // ================= 二、BeanFactory的初始化 =================
            // 对工厂进行默认后置处理
            postProcessBeanFactory(beanFactory);
            // 使用后置处理器对工厂进行处理
            invokeBeanFactoryPostProcessors(beanFactory);
            // 注册Bean后置处理器
            registerBeanPostProcessors(beanFactory);

            // ================= 三、事件,Bean及其他配置的初始化 =================
            // 初始化此上下文的消息源
            initMessageSource();
            // 为此上下文初始化事件广播者
            initApplicationEventMulticaster();
            // 初始化特定上下文子类中的其他特殊bean
            onRefresh();
            // 检查侦听器bean并注册
            registerListeners();
            // 实例化所有非懒加载的剩余单例
            finishBeanFactoryInitialization(beanFactory);
            // 完成刷新
            finishRefresh();
        }


        // ================= 异常处理 =================
        catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
            }
            // 销毁已创建的单例
            destroyBeans();
            // 重置上下文的激活状态
            cancelRefresh(ex);
            throw ex;
        }
        finally {
            // 重置内部的一些元数据缓存
            resetCommonCaches();
        }
    }
}

从总体来看,该方法描述的初始化过程大概分为三步:

笔者将基于 spring 源码 5.2.x 分支,分别通过五篇文章从源码分析 spring 容器的初始化过程。

本文是其中的第二篇文章,将介绍 BeanFactory 初始化。

相关文章:

一、对工厂进行默认后置处理

AbstractApplicationContext.postProcessBeanFactory()BeanFactory 的第一步,该过程用于在用户自定义的 BeanFactoryPostProcessor 前,对 BeanFactory 进行一些默认的配置。

AbstractApplicationContext 中,这个方法是个空实现,需要子类实现它的具体逻辑,但是无外乎都是做以下三件事:

  • BeanFactory 注册默认的 Bean 后置处理器;
  • BeanFactory 注册默认的 Bean 作用域;
  • BeanFactory 注册一些默认的 Bean

我们以一个典型的实现类 AbstractRefreshableWebApplicationContext 为例:

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 注册后置处理器ServletContextAwareProcessor
    beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
    beanFactory.ignoreDependencyInterface(ServletContextAware.class);
    beanFactory.ignoreDependencyInterface(ServletConfigAware.class);

    // 注册web环境下一些必要组件
    WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
    WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}

1、注册默认Bean后置处理器

postProcessBeanFactory() 最先调用了 BeanFactory.addBeanPostProcessor() 用于注册 ServletContextAwareProcessor 这个 Bean 后置处理器:

// beanFactory.addBeanPostProcessor
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
    Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
    // Remove from old position, if any
    this.beanPostProcessors.remove(beanPostProcessor);
    // Track whether it is instantiation/destruction aware
    if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
        this.hasInstantiationAwareBeanPostProcessors = true;
    }
    if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
        this.hasDestructionAwareBeanPostProcessors = true;
    }
    // Add to end of list
    this.beanPostProcessors.add(beanPostProcessor);
}

而对于 ServletContextAwareProcessor 这个类,我们只需要关注它实现的 postProcessBeforeInitialization 接口:

@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;
}

它将向所有实现了 ServletConfigAware 的 bean 注册 ServletContextServletConfig 这两个 bean,这也是为什么要在 postProcessBeanFactory

beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);

忽略 ServletContextAwareServletConfigAware 的原因了,因此 ServletContextAwareProcessor 已经完成了这两者的功能。

2、注册默认Bean作用域

registerWebApplicationScopes 方法主要用于注册 requestsessionglobalSessionapplication 这四个作用域:

public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,
                                                @Nullable ServletContext sc) {

    beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
    beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());
    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);
    }
}

3、注册默认Bean

registerEnvironmentBeans 方法用于注册 contextParameterscontextAttributes 这两个环境 bean:

public static void registerEnvironmentBeans(ConfigurableListableBeanFactory bf,
                                            @Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {

    if (servletContext != null && !bf.containsBean(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME)) {
        bf.registerSingleton(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME, servletContext);
    }

    if (servletConfig != null && !bf.containsBean(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME)) {
        bf.registerSingleton(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME, servletConfig);
    }

    if (!bf.containsBean(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME)) {
        Map<String, String> parameterMap = new HashMap<>();
        if (servletContext != null) {
            Enumeration<?> paramNameEnum = servletContext.getInitParameterNames();
            while (paramNameEnum.hasMoreElements()) {
                String paramName = (String) paramNameEnum.nextElement();
                parameterMap.put(paramName, servletContext.getInitParameter(paramName));
            }
        }
        if (servletConfig != null) {
            Enumeration<?> paramNameEnum = servletConfig.getInitParameterNames();
            while (paramNameEnum.hasMoreElements()) {
                String paramName = (String) paramNameEnum.nextElement();
                parameterMap.put(paramName, servletConfig.getInitParameter(paramName));
            }
        }
        bf.registerSingleton(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME,
                             Collections.unmodifiableMap(parameterMap));
    }

    if (!bf.containsBean(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME)) {
        Map<String, Object> attributeMap = new HashMap<>();
        if (servletContext != null) {
            Enumeration<?> attrNameEnum = servletContext.getAttributeNames();
            while (attrNameEnum.hasMoreElements()) {
                String attrName = (String) attrNameEnum.nextElement();
                attributeMap.put(attrName, servletContext.getAttribute(attrName));
            }
        }
        bf.registerSingleton(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME,
                             Collections.unmodifiableMap(attributeMap));
    }
}

二、使用后置处理器对工厂进行处理

在调用完 AbstractApplicationContext.postProcessBeanFactory() 后,BeanFactory 中已经具备了一些 spring 默认的配置,此时再调用 AbstractApplicationContext.invokeBeanFactoryPostProcessors 方法,使用用户提供的工厂后置处理器 BeanFactoryPostProcessorBeanFactory 进行后置处理。

AbstractApplicationContext 中,该方法实现如下:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // 借助后处理委托类调用全部的后置处理器
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    
    // 如果存在loadTimeWeaver这个bean,则会配置上LoadTimeWeaverAwareProcessor这个后置处理器
    // 然后设置临时的类加载器ContextTypeMatchClassLoader
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

// AbstractApplicationContext
public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
    return this.beanFactoryPostProcessors; // 这些是直接注册到上下文中的BeanFactoryPostProcessor
}

这里其实主要分为两部分逻辑:

  • 借助后处理器委托类 PostProcessorRegistrationDelegate 完成对 BeanFactory 的后置处理;
  • 如果引入了 AOP ,则需要为 BeanFactory 设置特殊的类加载器,从而允许生成 Bean 时织入切面逻辑;

第二部分很简洁,主要的逻辑都在第一部分。

1、后置处理委托类

这里又出现了一个新类 PostProcessorRegistrationDelegate,该类实际上是一个静态工具类,专门提供静态方法以用于处理上下文的后处理操作的,该类总共提供了两个方法:

  • invokeBeanFactoryPostProcessors():该方法用于对 BeanFactory 进行后置处理;
  • registerBeanPostProcessors():该方法用于向上下文中注册 Bean 的后置处理器;

2、对BeanFactory进行后置处理

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors() 这个方法非常的长,不过逻辑还是很明确的:

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) {

        // 将后置处理器分为两类:
        // 1.普通的BeanFactoryPostProcessor;
        // 2.BeanFactoryPostProcessor的子类BeanDefinitionRegistryPostProcessor;
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryProcessor =
                    (BeanDefinitionRegistryPostProcessor) postProcessor;
                // 若是BeanDefinitionRegistryPostProcessor,则先调用该类的postProcessBeanDefinitionRegistry方法
                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.
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

        // 先调用实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessors
        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);
        currentRegistryProcessors.clear();

        // 再调用实现了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();

        // 最后调用没实现PriorityOrdered或者Ordered接口的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();
        }

        // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    }

    // 如果BeanFactory没有实现BeanDefinitionRegistry接口
    else {
        // Invoke factory processors registered with the context instance.
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }

    // 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);

    // 过滤掉已经调用过的处理器,然后把处理器分为三类:
    // 1.实现了PriorityOrdered接口的处理器;
    // 2.实现了Ordered接口的处理器;
    // 3.没有实现PriorityOrdered或Ordered接口的处理器;
    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);
        }
    }

     // 调用实现了PriorityOrdered接口的后置处理器
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

    // 调用实现了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);

    // 调用没有实现PriorityOrdered或Ordered接口的后置处理器
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

    // 清除元数据
    beanFactory.clearMetadataCache();
}

由于 BeanFactoryPostProcessor 存在一个子接口 BeanDefinitionRegistryPostProcessor,它对应 BeanFactory 的一个子实现 BeanDefinitionRegistry,通过 BeanDefinitionRegistryPostProcessor 可以调整实现了 BeanDefinitionRegistryBeanFactory 中对 Bean 定义的一些信息。

由于 Bean 的定义肯定要比 Bean 的创建更优先,因此需要先执行 BeanDefinitionRegistryPostProcessor,然后再执行 BeanFactoryPostProcessor

同时,又由于 spring 提供了一套排序机制,即处理时优先处理实现了 PriorityOrdered 接口的处理器,再处理实现了 Ordered 接口的处理器,最后再处理两个接口都不实现的处理器,执行 BeanDefinitionRegistryPostProcessor,与执行 BeanFactoryPostProcessor 时都还要根据排序区分执行顺序。

因此,综合上文,这一步总体流程其实是这样的:

  • BeanFactory 实现了 BeanDefinitionRegistry 接口,则优先完成此步骤:
    1. 先调用实现了 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor
    2. 再调用实现了 Ordered 接口的 BeanDefinitionRegistryPostProcessor
    3. 最后调用没有实现上述两接口的 BeanDefinitionRegistryPostProcessor
  • 不管是否实现了 BeanDefinitionRegistry,都完成此步骤:
    1. 先调用实现了 PriorityOrdered 接口的 BeanFactoryPostProcessor
    2. 再调用实现了 Ordered 接口的 BeanFactoryPostProcessor
    3. 最后调用没有实现上述两接口的 BeanFactoryPostProcessor

三、注册Bean后置处理器

AbstractApplicationContext.registerBeanPostProcessors()BeanFactory 加载的第三步。这一步与调用 BeanFactory 一样,都通过后置处理委托类 PostProcessorRegistrationDelegate 进行:

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

registerBeanPostProcessors 与 上文调用 BeanFactory 后置处理器逻辑基本一致:

public static void registerBeanPostProcessors(
    ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

    // Register BeanPostProcessorChecker that logs an info message when
    // a bean is created during BeanPostProcessor instantiation, i.e. when
    // a bean is not eligible for getting processed by all BeanPostProcessors.
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

    // 依然将后置处理器分为三类:
    // 1.实现了PriorityOrdered接口的处理器;
    // 2.实现了Ordered接口的处理器;
    // 3.没有实现PriorityOrdered或Ordered接口的处理器;
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    List<String> orderedPostProcessorNames = new ArrayList<>();
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            // 这里是用于框架内部使用的后置处理器
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // 注册实现了PriorityOrdered接口的后置处理器
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // 注册实现了Ordered接口的后置处理器
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String ppName : orderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // 注册没有实现PriorityOrdered或Ordered接口的后置处理器
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String ppName : nonOrderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    // 注解框架内部使用的后置处理器
    sortPostProcessors(internalPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    // 重新注册ApplicationListenerDetector,保证该处理器总是位于处理器链的最后一位,从而总是在最后被执行
    // 该后置处理器用于支持spring的事件机制
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

上述这些代码的逻辑也很明确:

  1. 先注册实现了 PriorityOrdered 接口的 BeanPostProcessor
  2. 再注册实现了 Ordered 接口的 BeanPostProcessor
  3. 接着注册没有实现上述两接口的 BeanPostProcessor
  4. 然后再注册框架内部使用的 BeanPostProcessor
  5. 最后注册 ApplicationListenerDetector ,保证该后置处理器总是位于处理器链的末尾;

总结

当上下文刷新完毕,并且准备好了新的 BeanFactory 后,需要对 BeanFactory 进行三步操作以完成 BeanFactory 本身的初始化:

  1. postProcessBeanFactory:对 bean 工厂进行预处理,包括注册一些默认的 Bean 后置处理器,设置默认的 Bean 作用域,以及注册默认 Bean 等;

  2. invokeBeanFactoryPostProcessors:使用注册到上下文中的 BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessorBeanFactory 进行后置处理;

  3. registerBeanPostProcessors:注册 bean 的后处理器,包括用户自定义的、spring 内部使用的,以及用于支持事件机制的 ApplicationListenerDetector

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/170761.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Hadoop体系_集团架构

    Hadoop体系_集团架构目录2.1Hadoop简介2.1.1Hadoop由来2.1.2Hadoop发展历程2.1.3Hadoop生态系统2.2Hadoop的体系架构2.2.1分布式文件系统HDFS2.2.2分布式计算框架MapReduce2.2.3分布式资源调度系统YARN2.2.4三大发行版本2.1Hadoop简介自从大数据的概念被提出后,出现了很多相关技术,其中对大数据发展最有影响力的就是开源分布式计算平台Hadoop,它就像软件发展史上的Win…

    2022年10月17日
  • mybatis log plugin 2021 激活码(最新序列号破解)

    mybatis log plugin 2021 激活码(最新序列号破解),https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • Win系统 – 单通道 16G 内存 VS 双通道 16G 内存

    Win系统 – 单通道 16G 内存 VS 双通道 16G 内存单通道16GB测试成绩双通道16GB(8+8)测试成绩总结通过以上的一系列测试,不难看出单通道16GB与双通道16GB还是有一些差别的,究竟如何决择,笔者给大家分析一下。通过基础频率测试看出单通道16GB与双通道16GB内存条在性能参数、读取、写入、拷贝、复制、延迟及总体内存性能方面,还是存在着很大差距的;通过应用程序测试看出双通道16GB在解压缩方面比单通道16GB的速度要快接近1M/s,同理可以看出在双通道16GB在处理海量照片,视频软件等专业软件的能力要高出单通..

  • java语言打印出菱形_java怎么打印菱形

    java语言打印出菱形_java怎么打印菱形Java典型例题(打印菱形)题目:利用*号打印出一个菱形图样分析:下面逐步分析菱形打印的推演过程推演过程利用单独的方法演示,使用时直接在主方法中调用对应的方法即可。第一步,打印一行*号/**打印出如下图形: ********/publicstaticvoidprint01(){//每次打印一个星星for(inti=1;i<=7;i++){…

  • r语言熵权法求权重(真实案例完整流程)[通俗易懂]

    r语言熵权法求权重(真实案例完整流程)[通俗易懂]可以通过计算熵值来判断一个事件的随机性及无序程度,也可以用熵值来判断某个指标的离散程度,指标的离散程度越大,该指标对综合评价的影响(权重)越大。

  • 编写js程序实现n的阶乘_javascript矩阵算法

    编写js程序实现n的阶乘_javascript矩阵算法定义一个函数,算出n的阶乘/**定义一个函数,算出n的阶乘*/letx=Number(window.prompt(‘请输入求阶乘的数:’));console.log(jCheng(x))functionjCheng(x){ returnx<2?1:x*jCheng(x-1)}

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号