Spring4.3.x 容器的刷新过程

本文详细介绍了Spring容器的刷新流程,包括BeanFactory的创建、初始化、Bean后处理器的注册及单例bean的实例化等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述


Spring容器体系的继承结构图如下。

这里写图片描述

从图中可以看出抽象类AbstractApplicationContext是所有容器类的父类。AbstractApplicationContext实现了它继承的所有接口方法,并定义了三个用于管理BeanFactory对象的抽象方法,如下

    //---------------------------------------------------------------------
    // Abstract methods that must be implemented by subclasses
    //---------------------------------------------------------------------

    /**
     * Subclasses must implement this method to perform the actual configuration load.
     * The method is invoked by {@link #refresh()} before any other initialization work.
     * <p>A subclass will either create a new bean factory and hold a reference to it,
     * or return a single BeanFactory instance that it holds. In the latter case, it will
     * usually throw an IllegalStateException if refreshing the context more than once.
     * @throws BeansException if initialization of the bean factory failed
     * @throws IllegalStateException if already initialized and multiple refresh
     * attempts are not supported
     */
    protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;

    /**
     * Subclasses must implement this method to release their internal bean factory.
     * This method gets invoked by {@link #close()} after all other shutdown work.
     * <p>Should never throw an exception but rather log shutdown failures.
     */
    protected abstract void closeBeanFactory();

    /**
     * Subclasses must return their internal bean factory here. They should implement the
     * lookup efficiently, so that it can be called repeatedly without a performance penalty.
     * <p>Note: Subclasses should check whether the context is still active before
     * returning the internal bean factory. The internal factory should generally be
     * considered unavailable once the context has been closed.
     * @return this application context's internal bean factory (never {@code null})
     * @throws IllegalStateException if the context does not hold an internal bean factory yet
     * (usually if {@link #refresh()} has never been called) or if the context has been
     * closed already
     * @see #refreshBeanFactory()
     * @see #closeBeanFactory()
     */
    @Override
    public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;

小技巧:告诉大家如何查看一个抽象类未实现的接口方法有哪些,比如上面的AbstractApplicationContext抽象类。我创建了一个MyApplicationContext 类,如果未实现任何方法,IDE会提醒我实现父类中未实现的方法,代码如下。

public class MyApplicationContext extends AbstractApplicationContext {
    @Override
    protected void refreshBeanFactory() throws BeansException, IllegalStateException {

    }

    @Override
    protected void closeBeanFactory() {

    }

    @Override
    public ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException {
        return null;
    }
}

回归正题,Spring容器在初始化的时候都会执行一个方法来结束初始化,那就是refresh()方法,此方法定义在接口ConfigurableApplicationContext中,并且抽象类AbstractApplicationContext实现了它,代码如下

    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 为容器的刷新做准备工作,设置启动日期,更新活动标志,加载属性资源
            prepareRefresh();

            // 获取最新的bean工厂对象。
            // 要求子类刷新自身持有的bean工厂对象
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // 在容器使用bean工厂之前,设置bean工厂
            // 主要是添加特定的bean后处理器
            prepareBeanFactory(beanFactory);

            try {
                // 钩子方法,允许在子类中bean工厂做进一步的处理
                // 子类可以根据自身需要,添加更多的bean后处理器
                postProcessBeanFactory(beanFactory);

                // 在上下文容器中执行所有注册了的bean工厂后处理器
                // 执行步骤:1. 在bean工厂中找到所有实现了BeanFactoryPostProcessor的对象
                // ->2. 执行所有bean工厂后处理器的postProcessBeanFactory方法
                invokeBeanFactoryPostProcessors(beanFactory);

                // 把所有用户配置的bean后处理器添加到bean工厂中
                registerBeanPostProcessors(beanFactory);

                // 初始化国际化消息对象,默认为DelegatingMessageSource
                initMessageSource();

                // 初始化事件传播器,默认为SimpleApplicationEventMulticaster
                initApplicationEventMulticaster();

                // 钩子方法,初始化其他特定的bean
                onRefresh();

                // 注册用户指定的和容器创建时添加的监听器
                registerListeners();

                // 初始化所有剩下的单例非延迟bean
                finishBeanFactoryInitialization(beanFactory);

                // 完成刷新,包括发布容器刷新事件
                finishRefresh();
            } catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                /// 销毁所有已经创建好的bean,以防止内存浪费
                destroyBeans();

                // 重置活动标志
                cancelRefresh(ex);

                throw ex;
            } finally {
                // 重置反射缓存
                resetCommonCaches();
            }
        }
    }

refresh方法的设计使用了模板方法设计模式,它设定了容器刷新的流程,并把特定阶段的执行延迟到子类中执行,比如bean工厂的创建。它还在特定的阶段提供钩子方法,以方便子类根据自身需要进一步完成更多的操作。下面我们一步一步的探讨refresh方法的执行流程。下图是它的一个大概流程图。

refresh方法在容器的基本配置完成后被调用,它是spring容器初始化过程的主要战场,下面我们一步一步的探讨refresh方法的执行流程。

容器刷新过程


1. 容器刷新前准备

在refresh方法的第1步中,调用AbstractApplicationContext的prepareRefresh()方法完成容器刷新前的准备,代码如下。

    protected void prepareRefresh() {
        // 设置启动时间
        this.startupDate = System.currentTimeMillis();

        this.closed.set(false);
        // 把容器设置为活动
        this.active.set(true);

        if (logger.isInfoEnabled()) {
            logger.info("Refreshing " + this);
        }

        // 钩子方法,让子类把所有的stub属性资源替换成真正需要的属性资源。
        initPropertySources();

        // 验证所有被标注为required的属性是否可被解析
        getEnvironment().validateRequiredProperties();

        // 允许事件传播器可用的时候发布一些事件
        // earlyApplicationEvents存储需要在事件传播器可用时发布的事件
        this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
    }

prepareRefresh方法设置容器启动时间和活动标志,以及通过调用initPropertySources()方法完成所有的property资源的初始化。initPropertySources()方法是一个空实现,子类可以用它来完成property资源的初始化。例如,下面代码是在AbstractRefreshableWebApplicationContext类中的实现

    @Override
    protected void initPropertySources() {
        super.initPropertySources();
        ConfigurableEnvironment env = this.getEnvironment();
        if (env instanceof ConfigurableWebEnvironment) {
            ((ConfigurableWebEnvironment)env).initPropertySources(
                    this.servletContext, this.servletConfig);
        }
    }

这个方法主要是把ServletContext和ServletConfig对象保存到ConfigurableWebEnvironment环境对象中,以方便环境对象通过getProperty(String key)方法获取定义在ServletContext和ServletConfig中特定的初始化init-param参数。

2. 创建BeanFactory

执行AbstractApplicationContext的obtainFreshBeanFactory方法,获取最新的bean工厂对象,代码如下。

    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        // 刷新bean工厂,是一个抽象方法,由子类实现。
        refreshBeanFactory();
        // 从子类中获取bean工厂,也是一个抽象方法,由子类实现
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        if (logger.isDebugEnabled()) {
            logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
        }
        return beanFactory;
    }

obtainFreshBeanFactory方法首先调用子类的refreshBeanFactory()方法刷新bean工厂,然后调用子类的getBeanFactory()方法获取bean工厂。在spring中,refreshBeanFactory()在GenericApplicationContext类和AbstractRefreshableApplicationContext类中都有实现,下面是在AbstractRefreshableApplicationContext类中的实现。

    @Override
    protected final void refreshBeanFactory() throws BeansException {
        if (hasBeanFactory()) {
            // 如果当前上线文容器已有bean工厂
            // 销毁bean工厂中所有单例bean
            destroyBeans();
            // 关闭已有的bean工厂
            closeBeanFactory();
        }
        try {

            // 创建一个新的bean工厂
            DefaultListableBeanFactory beanFactory = createBeanFactory();
            beanFactory.setSerializationId(getId());
            // 自定义bean工厂,包括设置是否允许覆盖相同ID的bean,是否允许循环引用,等等
            customizeBeanFactory(beanFactory);
            // 加载所有BeanDefinition,是一个抽象方法,有子类实现
            loadBeanDefinitions(beanFactory);
            synchronized (this.beanFactoryMonitor) {
                this.beanFactory = beanFactory;
            }
        } catch (IOException ex) {
            throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
        }
    }

这个方法里面,首先把已创建的单例bean销毁并关闭持有的bean工厂,然后调用createBeanFactory()方法重新创建一个x新的bean工厂代码如下。最后,并调用子类的loadBeanDefinitions方法把BeanDefinition对象加载到bean工厂中。

    /**
        * 创建一个新的bean工厂
    **/
    protected DefaultListableBeanFactory createBeanFactory() {
        return new DefaultListableBeanFactory(getInternalParentBeanFactory());
    }

3. 初始化BeanFactory

获取到BeanFactory对象后,refresh()方法调用AbstractApplicationContext对象的prepareBeanFactory方法和postProcessBeanFactory方法完成bean工厂的初始化。在这个阶段,容器中所有的BeanDefinition对象已经被注册到bean工厂中(除被@Configuration注解的类管理的bean配置外),但是没有任何一个BeanDefinition所代表的bean被创建,包括工厂后处理器。下面我们看看这个两个方法的执行情况。

首先,调用prepareBeanFactory方法。这个方法主要功能是,为bean工厂设置容器的类加载器,以及一些特定的bean后处理器,代码如下。

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 要求bean工厂和容器共用同一个类加载器
        beanFactory.setBeanClassLoader(getClassLoader());
        // 设置SpEL表达式解析器
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
        // 添加Resource编辑器注册器
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

        // 添加ApplicationContextAwareProcessor后处理器
        // 有可能某些工厂后处理器实现了ApplicationContextAware、ResourceLoaderAware等等如下类似接口
        // ApplicationContextAwareProcessor后处理器就就为这些接口传递相应的对象
        // 因此,在执行工厂后处理器前,必须要设置此后处理器
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);

        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);

        // Detect a LoadTimeWeaver and prepare for weaving, if found.
        // 检测用户是否配置了loadTimeWeaver bean对象
        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            // 添加LoadTimeWeaverAwareProcessor后处理器,此后处理器用于向bean中注入LoadTimeWeaver对象
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            // 为类型匹配检测配置临时的类加载器
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        // 注册默认的环境bean对象
        if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
        }
        // 注册OS系统属性对象
        if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
        }
        // 注册OS系统环境对象
        if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
        }
    }

然后,调用postProcessBeanFactory方法。这个方法在AbstractApplicationContext类中的定义如下。

    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    }

postProcessBeanFactory方法被作为钩子方法,让子类在bean工厂初始化的时候根据自身需要,对bean工厂做更多的操作。在web应用中,AbstractRefreshableWebApplicationContext类重写此方法,代码如下。

    /**
     * 注册request/session作用域, 和ServletContextAwareProcessor bean后处理器, .
     */
    @Override
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 添加ServletContextAwareProcessor后处理器
        beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
        beanFactory.ignoreDependencyInterface(ServletContextAware.class);
        beanFactory.ignoreDependencyInterface(ServletConfigAware.class);

        // 注册request/session作用域
        WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
        // 把ServletContext对象和ServletConfig对象等以单例bean的形式注册到bean工厂中
        WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
    }

4. 执行bean工厂后处理器的postProcessBeanFactory方法

bean工厂初始化完成后,refresh()方法调用AbstractApplicationContext的invokeBeanFactoryPostProcessors方法完成容器中所有bean工厂后处理器的执行,代码如下。

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        // 把执行工厂后处理器的任务委托给PostProcessorRegistrationDelegate
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

        // 检测LoadTimeWeaver对象
        // 声明:String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";
        if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
    }

这段代码主要是把工厂后处理器的任务委托给PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors方法,此方法的代码如下。

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

         // 首先执行BeanDefinitionRegistryPostProcessors
        Set<String> processedBeans = new HashSet<String>();

        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
            List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
                    new LinkedList<BeanDefinitionRegistryPostProcessor>();
            // 遍历容器中的工厂后处理器,并执行BeanDefinitionRegistryPostProcessors
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryPostProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    // 执行BeanDefinitionRegistryPostProcessors的
                    // ->postProcessBeanDefinitionRegistry方法
                    registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryPostProcessors.add(registryPostProcessor);
                }
                else {
                    regularPostProcessors.add(postProcessor);
                }
            }

             // 获取bean工厂中定义的BeanDefinitionRegistryPostProcessor对象
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

            // 首先,执行实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor对象
            List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
            for (String ppName : postProcessorNames) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
            registryPostProcessors.addAll(priorityOrderedPostProcessors);
            invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);

            // 然后,执行实现了Ordered接口的BeanDefinitionRegistryPostProcessor对象
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
            for (String ppName : postProcessorNames) {
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(beanFactory, orderedPostProcessors);
            registryPostProcessors.addAll(orderedPostProcessors);
            invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);

            // 最后执行其它的BeanDefinitionRegistryPostProcessor对象
            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                for (String ppName : postProcessorNames) {
                    if (!processedBeans.contains(ppName)) {
                        BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
                        registryPostProcessors.add(pp);
                        processedBeans.add(ppName);
                        pp.postProcessBeanDefinitionRegistry(registry);
                        reiterate = true;
                    }
                }
            }

            // 执行BeanDefinitionRegistryPostProcessor工厂后处理器
            invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
            // 执行容器中普通的工厂后处理器
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        } else {
            // 执行容器中的bean工厂后处理器
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        // 获取定义在bean工厂中的bean工厂后处理器
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        // 把bean工厂后处理器按PriorityOrdered、Ordered和其他来分类
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
        List<String> orderedPostProcessorNames = new ArrayList<String>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
        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);
            }
        }

        // 首先执行实现了PriorityOrdered接口的后处理器
        sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // 然后执行实现了Ordered接口的后处理器
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        sortPostProcessors(beanFactory, orderedPostProcessors);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        //  最后执行其他的后处理器
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

        // 清除工厂中的元数据缓存
        beanFactory.clearMetadataCache();
    }
    /**
     * 执行给定的BeanDefinitionRegistryPostProcessor beans.
     */
    private static void invokeBeanDefinitionRegistryPostProcessors(
            Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

        for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
            postProcessor.postProcessBeanDefinitionRegistry(registry);
        }
    }
    /**
    * 执行给定的bean工厂
    **/
    private static void invokeBeanFactoryPostProcessors(
            Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

        for (BeanFactoryPostProcessor postProcessor : postProcessors) {
            postProcessor.postProcessBeanFactory(beanFactory);
        }
    }

上面的执行流程用图表达如下。
这里写图片描述

上图很明显的表达了bean工厂后处理器的执行顺序,但这里还有两点需要说明的。

a. 为什么要先执行BeanDefinitionRegistryPostProcessor?因为实现BeanDefinitionRegistryPostProcessor 接口的后处理器可以在bean工厂创建其他bean之前添加更多的BeanDefinition对象到bean工厂中去。比如spring中ConfigurationClassPostProcessor类就是这样一种工厂后处理器,它主要把被@Configuration注解的类中定义的bean信息转换成BeanDefinition对象,并注册到bean工厂中。

b. 这个流程中有一个很明显的规定就是,不管是什么工厂后处理器,都必须先执行容器中的工厂后处理器后,才执行bean工厂中的工厂后处理器。

5. 注册BeanPostProcessor

refresh()方法执行完bean工厂后处理器后,接着调用AbstractApplicationContext的registerBeanPostProcessors方法向bean工厂注册bean后处理器,registerBeanPostProcessors方法的代码如下。

    protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        // 把注册bean后处理器的任务委托给PostProcessorRegistrationDelegate
        PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
    }

registerBeanPostProcessors方法把注册bean后处理器的任务委托给PostProcessorRegistrationDelegate类的registerBeanPostProcessors方法,下面是这个方法的代码。

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

        // 从bean工厂中找到所有BeanPostProcessor对象的名称
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

        // 注册BeanPostProcessorChecker后处理器
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

        // 对所有的bean后处理器根据实现PriorityOrdered,Ordered和其他的进行分组
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
        List<String> orderedPostProcessorNames = new ArrayList<String>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
        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接口的bean后处理器
        sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

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

        // 再次,注册所有普通的后处理器
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
        for (String ppName : nonOrderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

        // 最后,重新注册所有内部后处理器
        // ->即实现了MergedBeanDefinitionPostProcessor接口的后处理器
        sortPostProcessors(beanFactory, internalPostProcessors);
        registerBeanPostProcessors(beanFactory, internalPostProcessors);

        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }
    /**
     * 注册指定的BeanPostProcessor beans.
     */
    private static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

        for (BeanPostProcessor postProcessor : postProcessors) {
            beanFactory.addBeanPostProcessor(postProcessor);
        }
    }

这部分代码注册bean后处理器的注册流程如下。

这里写图片描述

整个流程根据PriorityOrdered、Ordered、非Ordered的顺序注册bean后处理器,最后注册MergedBeanDefinitionPostProcessor bean后处理器。其中MergedBeanDefinitionPostProcessor会在其他bean后处理器执行前执行它的postProcessMergedBeanDefinition方法。

6. 初始化MessageSource国际化消息

执行AbstractApplicationContext的initMessageSource方法,代码如下

    protected void initMessageSource() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        // 声明:public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";
        // 检测用户是否指定了messageSource
        if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
            this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
            // 使当前messageSource能够使用父容器中的messageSource
            if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
                HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
                if (hms.getParentMessageSource() == null) {
                    hms.setParentMessageSource(getInternalParentMessageSource());
                }
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Using MessageSource [" + this.messageSource + "]");
            }
        }
        else {
            // 用户没有指定messageSource
            // 使用一个空的MessageSource,以能够接受getMessage方法的调用
            DelegatingMessageSource dms = new DelegatingMessageSource();
            dms.setParentMessageSource(getInternalParentMessageSource());
            this.messageSource = dms;
            beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
                        "': using default [" + this.messageSource + "]");
            }
        }
    }

注意:如果要使用国际化消息,必须提供bean名称为messageSource的MessageSource对象,形如下面的配置。

    <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
        <property name="basenames">
            <list>
                <value>/WEB-INF/languages/globe/messages</value>
            </list>
        </property>
        <property name="cacheSeconds" value="1800"/>
        <property name="defaultEncoding" value="UTF-8"/>
    </bean>

7. 初始化事件传播器

refresh()方法完成国际化消息对象初始化后,接着调用AbstractApplicationContext的initApplicationEventMulticaster方法为容器添加事件传播器,代码如下。

    protected void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        // 声明:public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";
        // 检测用户是否制定了事件传播器
        if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
            this.applicationEventMulticaster =
                    beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
            if (logger.isDebugEnabled()) {
                logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
            }
        }
        else {
            // 使用默认的事件传播器
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                        APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                        "': using default [" + this.applicationEventMulticaster + "]");
            }
        }
    }

8. 其他初始化

refresh()方法完成国际化消息和事件传播器的初始化后,把容器的初始化交给onRefresh()方法,代码如下。

    protected void onRefresh() throws BeansException {
        // For subclasses: do nothing by default.
    }

onRefresh()方法被设计成容器初始化的钩子,以方便子类初始化其他特定的bean。例如,下面是在AbstractRefreshableWebApplicationContext类中onRefresh()方法被重写的代码。

    /**
     * Initialize the theme capability.
     */
    @Override
    protected void onRefresh() {
        this.themeSource = UiApplicationContextUtils.initThemeSource(this);
    }

其中,UiApplicationContextUtils工具类的initThemeSource(ApplicationContext context)方法的代码如下。

    public static ThemeSource initThemeSource(ApplicationContext context) {
        // 声明有:public static final String THEME_SOURCE_BEAN_NAME = "themeSource";
        if (context.containsLocalBean(THEME_SOURCE_BEAN_NAME)) {
            ThemeSource themeSource = context.getBean(THEME_SOURCE_BEAN_NAME, ThemeSource.class);
            // 使themeSource关联父容器,这个父容器必须实现了ThemeSource接口
            if (context.getParent() instanceof ThemeSource && themeSource instanceof HierarchicalThemeSource) {
                HierarchicalThemeSource hts = (HierarchicalThemeSource) themeSource;
                if (hts.getParentThemeSource() == null) {

                    hts.setParentThemeSource((ThemeSource) context.getParent());
                }
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Using ThemeSource [" + themeSource + "]");
            }
            return themeSource;
        }
        else {
            HierarchicalThemeSource themeSource = null;
            if (context.getParent() instanceof ThemeSource) {
                // 把对ThemeSource的操作代理给父容器
                themeSource = new DelegatingThemeSource();
                themeSource.setParentThemeSource((ThemeSource) context.getParent());
            } else {
                // 使用默认的ThemeSource
                themeSource = new ResourceBundleThemeSource();
            }
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate ThemeSource with name '" + THEME_SOURCE_BEAN_NAME +
                        "': using default [" + themeSource + "]");
            }
            return themeSource;
        }
    }

9. 注册监听器

执行完成子类实现的onRefresh()方法,需要向容器中注册各种监听器,此时执行AbstractApplicationContext的registerListeners()方法,这个方法的代码如下。

    protected void registerListeners() {
        // 首先注册容器中特定的事件监听器
        for (ApplicationListener<?> listener : getApplicationListeners()) {
            getApplicationEventMulticaster().addApplicationListener(listener);
        }

        // 找到用户配置的所有的监听器bean名称
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        for (String listenerBeanName : listenerBeanNames) {
            // 在事件传播器中只保存监听器的bean名称
            // 这里不实例化监听器的原因是为了让后处理器在它们真正实例化的时候作用于它们
            getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        // 发布那些需要提前发布的事件
        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }

10. 实例化非延迟单例bean

前面所有的初始化操作都完成了后,则开始实例化剩下的单例非延迟加载的bean。通过执行AbstractApplicationContext的finishBeanFactoryInitialization方法完成,这个方法的代码如下。

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // 初始化ConversionService
        // 在ConfigurableApplicationContext接口中声明:String CONVERSION_SERVICE_BEAN_NAME = "conversionService";
        if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
            beanFactory.setConversionService(
                    beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
        }

        // 注册一个默认的内部value解析器
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
                @Override
                public String resolveStringValue(String strVal) {
                    return getEnvironment().resolvePlaceholders(strVal);
                }
            });
        }

        // 初始化LoadTimeWeaverAware对象来支持注册他们的transformers
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }

        // 停止使用临时类加载器来做类型匹配
        beanFactory.setTempClassLoader(null);

        // 允许缓存所有的bean元数据定义,不希望今后再更改
        beanFactory.freezeConfiguration();

        // 初始化所有非延迟单例bean
        beanFactory.preInstantiateSingletons();
    }

11. 完成刷新

refresh()方法的最后一步,AbstractApplicationContext的finishRefresh方法,完成容器刷新,执行LifecycleProcessor对象的onRefresh方法,以及发布刷新事件。代码如下,

    protected void finishRefresh() {
        // 初始化生命周期处理器,默认为DefaultLifecycleProcessor 
        initLifecycleProcessor();

        // Propagate refresh to lifecycle processor first.
        // 首先把刷新操作传递给生命周期处理器
        getLifecycleProcessor().onRefresh();

        // 最后发布容器刷新事件
        publishEvent(new ContextRefreshedEvent(this));

        // 把spring容器加入到LiveBeansView的MBeanServer中
        LiveBeansView.registerApplicationContext(this);
    }
    /**
    * 初始化生命周期处理器
    **/
    protected void initLifecycleProcessor() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        // 声明:public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor";
        if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
            // 使用用户指定的生命周期处理器
            this.lifecycleProcessor =
                    beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
            if (logger.isDebugEnabled()) {
                logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
            }
        }
        else {
            // 使用默认的声明周期处理器
            DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
            defaultProcessor.setBeanFactory(beanFactory);
            this.lifecycleProcessor = defaultProcessor;
            beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
            if (logger.isDebugEnabled()) {
                logger.debug("Unable to locate LifecycleProcessor with name '" +
                        LIFECYCLE_PROCESSOR_BEAN_NAME +
                        "': using default [" + this.lifecycleProcessor + "]");
            }
        }
    }

到这里spring的刷新也就完成了。

总结


(1)spring的所有容器都直接或间接继承了抽象类AbstractApplicationContext。

(2) spring的容器在创建并完成基本的配置后,在初次使用前,还必须执行refresh()方法。

(3)实现BeanDefinitionRegistryPostProcessor 接口的后处理器可以在bean工厂创建其他bean之前添加更多的BeanDefinition对象到bean工厂中去。比如spring中ConfigurationClassPostProcessor类,它主要把被@Configuration注解的类中定义的bean信息转换成BeanDefinition对象,并注册到bean工厂中。

(4)可以自定义BeanPostProcessor工厂后处理器对BeanDefinition对象做处理,比如spring的PreferencesPlaceholderConfigurer工厂后处理器,它把属性文件中的值与BeanDefinition中相应的属性值相替换。

(5)指定国际化消息时,MessageSource对象的bean名称必须为messageSource。

(6)容器刷新过程中的钩子方法有:
a. initPropertySources()由子类根据自身的应用环境初始化property资源。
b. postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)用于在bean工厂后处理器执行前由子类对bean工厂做更多的初始化操作。
c. onRefresh()用于初始化子类中特定的bean。

(7)LiveBeansView的使用

Spring容器初始化过程中的最后一步,把spring容器加入到LiveBeansView的MBeanServer中。这个LiveBeansView它是一个MBean对象,它的作用是查看当前活动的bean以及这些bean的依赖。下面步骤介绍如何使用它。

a. 在web.xml文件配置如下,其中param-value可以任意取

    <context-param>
        <param-name>spring.liveBeansView.mbeanDomain</param-name>
        <param-value>chyohn_liveBeansView</param-value>
    </context-param>

b. 启动应用后,打开%JAVA_HOME%/bin/jconsole.exe程序,如下

这里写图片描述

c. 我使用的tomcat服务器启动的,点击第2个链接,进入的页面,如下

这里写图片描述

上面的JSON数据中就包含当前spring容器中所有的bean,是不是很神奇?这也是java MBean的一个例子。

### 中职学校网络安全理论课程大纲和教学内容 #### 2025年中职学校网络安全理论课程概述 随着信息技术的发展网络安全已成为信息化社会的重要组成部分。为了适应这一需求,中职学校的网络安全理论课程旨在培养学生具备基本的网络安全意识和技术能力,使学生能够在未来的职业生涯中应对各种网络威胁。 #### 教学目标 该课程的目标是让学生理解网络安全的基本概念、原理和技术手段,掌握常见的安全防护措施,并能应用这些知识解决实际问题。具体来说,学生应达到以下几点: - 掌握计算机网络基础架构及其工作原理; - 理解信息安全管理体系框架及其实现方法; - 学习密码学基础知识以及加密算法的应用场景; - 能够识别常见攻击方式并采取有效防御策略; #### 主要章节安排 ##### 第一章 计算机网络与互联网协议 介绍计算机网络的基础结构和服务模型,重点讲解TCP/IP五层体系结构中的各层次功能特点,特别是传输控制协议(TCP)和用户数据报协议(UDP)[^1]。 ##### 第二章 信息系统安全保障概论 探讨信息系统的脆弱性和风险评估机制,阐述如何通过物理隔离、访问控制等措施来保障系统安全性。 ##### 第三章 密码学入门 讲述对称密钥体制和非对称密钥体制的区别与发展历程,分析公钥基础设施(PKI)的工作流程及其重要性。 ##### 第四章 防火墙技术与入侵检测系统(IDS) 解释防火墙的作用原理及其分类形式(包过滤型、代理服务器型),讨论IDS的功能特性及部署建议。 ##### 第五章 Web应用程序安全 针对Web环境下的特殊挑战展开论述,如SQL注入漏洞利用、跨站脚本(XSS)攻击防范等内容。 ##### 实践环节设置 除了上述理论部分外,在每学期还设有专门实践课时用于模拟真实环境中可能遇到的安全事件处理过程,增强学生的动手操作能力和应急响应水平。 ```python # Python代码示例:简单的MD5哈希函数实现 import hashlib def md5_hash(text): hasher = hashlib.md5() hasher.update(text.encode('utf-8')) return hasher.hexdigest() print(md5_hash("example")) ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值