zoukankan      html  css  js  c++  java
  • 基于AnnotationConfigApplicationContext的容器创建过程(Spring Version 5.2.0)

    首先你要引入依赖

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.0.RELEASE</version>
    </dependency>

    然后你得有个配置类

    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class SimpleConfig {
    }

    最后是启动程序

    public static void main(String[] args){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SimpleConfig.class);
    }

    开始

    进入构造方法

    public AnnotationConfigApplicationContext(Class... componentClasses) {
        this();
        this.register(componentClasses);
        this.refresh();
    }

    这种情况分为三步:

    1. 调用重载构造方法,目的是初始化bean定义扫描器。

    public AnnotationConfigApplicationContext() {
        // 这是{ClassPathBeanDefinitionScanner}的另一种选择,它应用了相同的注释解析,但是只针对显式注册的类。
        this.reader = new AnnotatedBeanDefinitionReader(this);
        // 一个bean定义扫描器,它检测类路径上的候选bean,在给定的注册中心注册相应的bean定义({BeanFactory}或{ApplicationContext})。
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }

    2. 注册给定的配置类

    public void register(Class... componentClasses) {
        Assert.notEmpty(componentClasses, "At least one component class must be specified");
        // 实际上调用AnnotatedBeanDefinitionReader#doRegisterBean,注册给定的bean
        this.reader.register(componentClasses);
    }

    3. 刷新。

    // 实际上调用的父类刷新方法
    org.springframework.context.support.AbstractApplicationContext#refresh

    refresh方法

    先看下整个流程

    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 1. 为上下文刷新做准备:设置其启动开始时间和活动标志以及执行任何属性源的初始化。初始化earlyApplicationListeners和earlyApplicationEvents。
            prepareRefresh();
    
            // 2. 告诉子类刷新内部bean工厂。返回这个上下文所持有的内部BeanFactory
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
            // ☆☆☆3. 准备bean工厂以供在此上下文中使用。配置工厂的标准上下文特征,比如上下文的类加载器、后置处理器。
            prepareBeanFactory(beanFactory);
    
            try {
                // 4. 由上下文子类实现的方法,对bean工厂的后置处理
                // 这个时候所有bean定义都已加载,但还没有实例化bean。这允许在特定的ApplicationContext实现中注册特殊的BeanPostProcessors
                postProcessBeanFactory(beanFactory);
    
                // ☆☆☆5. 调用上下文中注册为bean的工厂处理器。
                // 实例化并调用所有已注册的BeanFactoryPostProcessor bean,必须在单例(singleton)实例化之前调用。
                // 实际上是由工具类PostProcessorRegistrationDelegate负责调用执行的。
                // ***BeanFactoryPostProcessor,是针对整个工厂生产出来的BeanDefinition作出修改或者注册。作用于BeanDefinition时期。
                invokeBeanFactoryPostProcessors(beanFactory);
    
                // ☆☆☆6. 注册拦截bean创建的bean处理器。
                // 实例化并注册所有BeanPostProcessor bean,如果给定,则遵循显式顺序。必须在任何应用程序bean的实例化之前调用。
                // 实际上是由工具类PostProcessorRegistrationDelegate负责调用执行的。
                // ***BeanPostProcessor 在bean实例化、初始化前后执行
                registerBeanPostProcessors(beanFactory);
    
                // 7. 为上下文初始化消息源。
                // MessageSource干嘛用的:比如国际化
                initMessageSource();
    
                // ☆☆☆8. 为上下文初始化事件广播程序。初始化ApplicationEventMulticaster。如果上下文中没有定义,则使用SimpleApplicationEventMulticaster。
                initApplicationEventMulticaster();
    
                // 9. 由上下文的子类实现的方法,初始化其它特殊Bean
                // 模板方法,可以覆盖该方法以添加特定于上下文的刷新工作。在单例(singleton)实例化之前,在初始化特殊bean时调用。
                onRefresh();
    
                // ☆☆☆10. 检查监听器bean并注册它们。
                // 添加的是ApplicationListener的实现类。发布事件的是ApplicationEventMulticaster,接收事件的是ApplicationListener。
                registerListeners();
    
                // ☆☆☆11. 实例化所有剩余的(非懒加载)单例。
                finishBeanFactoryInitialization(beanFactory);
    
                // ☆☆☆12. 最后一步:发布相应的事件。
                finishRefresh();
            }
    
            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }
    
                // ☆☆☆13. 销毁已经创建的单例,以避免挂起资源。
                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();
            }
        }
    }

    流程总结:

    1. 为上下文刷新做准备:设置其启动开始时间和活动标志以及执行任何属性源的初始化。初始化earlyApplicationListeners和earlyApplicationEvents。

    2. 告诉子类刷新内部bean工厂。返回这个上下文所持有的内部BeanFactory。

    3. 准备bean工厂以供在此上下文中使用。配置工厂的标准上下文特征,比如上下文的类加载器、后置处理器。

    4. 由上下文子类实现的方法,对bean工厂的后置处理。

    5. 调用上下文中注册为bean的工厂处理器(BeanFactoryPostProcessor)。

    6. 注册拦截bean创建的bean处理器。(BeanPostProcessor)

    7. 为上下文初始化消息源。

    8. 为上下文初始化事件广播程序。初始化ApplicationEventMulticaster。如果上下文中没有定义,则使用SimpleApplicationEventMulticaster。

    9. 由上下文的子类实现的方法,初始化其它特殊Bean。

    10. 检查监听器bean并注册它们。和第8步协作。

    11. 实例化所有剩余的(非懒加载)单例。

    12. 最后一步:发布相应的事件。

    如果发生异常----->

    13. 销毁已经创建的单例,以避免挂起资源。

    下面步骤拆分

    0. 刷新过程有几个地方是由子类实现的,这里先做个例子

    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    /**
     * Created by 小LUA on 2020-02-24 10:27.
     */
    public class MyApp extends AnnotationConfigApplicationContext {
        public MyApp(Class<?>... componentClasses) {
            super(componentClasses);
        }
    
        @Override
        protected void initPropertySources() {
            super.initPropertySources();
            System.out.println("子类实现,初始化其它属性源...");
        }
    
        @Override
        protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
            super.postProcessBeanFactory(beanFactory);
            System.out.println("子类实现对bean工厂的后置处理...");
        }
    
        @Override
        protected void onRefresh() throws BeansException {
            super.onRefresh();
            System.out.println("子类实现初始化其他特殊Bean...");
        }
    
        public static void main(String[] args){
            ApplicationContext context = new MyApp(SimpleConfig.class);
    //        ApplicationContext context = new AnnotationConfigApplicationContext(SimpleConfig.class);
        }
    }

    输出

    1. 为上下文刷新做准备

    protected void prepareRefresh() {
        // 启动开始时间
        this.startupDate = System.currentTimeMillis();
        // 设置活动开关
        this.closed.set(false);
        this.active.set(true);
        if (logger.isDebugEnabled()) {
            if (logger.isTraceEnabled()) {
                logger.trace("Refreshing " + this);
            }
            else {
                logger.debug("Refreshing " + getDisplayName());
            }
        }
        // 在上下文环境中初始化任何占位符属性源。这里是由子类实现的。
        initPropertySources();
        // 验证所有标记为需要的属性都是可解析的
        getEnvironment().validateRequiredProperties();
        // 存储预刷新的 ApplicationListeners
        if (this.earlyApplicationListeners == null) {
            this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
        }
        else {
            // 将本地应用程序监听器重置为预刷新状态。
            this.applicationListeners.clear();
            this.applicationListeners.addAll(this.earlyApplicationListeners);
        }
        // 初始化早期事件容器。收集早期的应用程序事件,一旦广播者 multicaster 可用,这里存储的事件将被发布
        this.earlyApplicationEvents = new LinkedHashSet<>();
    }

    这里可以理解为:飞机起飞之前肯定要先启动(prepareRefresh),这个时候肯定要先看一下基础功能是否正常。

    > 启动时间

    > 系统状态更新为已激活

    > 执行附加的操作(子类实现

    > 事件广播者和收听者准备就绪

    2. 告诉子类刷新内部bean工厂。返回这个上下文所持有的内部BeanFactory。

    protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        // 设置refreshed标志位为true
        refreshBeanFactory();
        // 返回内部BeanFactory
        return getBeanFactory();
    }
    protected final void refreshBeanFactory() throws IllegalStateException {
        if (!this.refreshed.compareAndSet(false, true)) {
            throw new IllegalStateException(
                    "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
        }
        this.beanFactory.setSerializationId(getId());
    }
    public final ConfigurableListableBeanFactory getBeanFactory() {
        return this.beanFactory;
    }

    这一步只做了两件事,可以理解为:飞机已经决定起飞(refreshed)了

    > 设置refreshed标志位为true

    > 返回内部BeanFactory

    3. ☆☆☆准备bean工厂以供在此上下文中使用。配置工厂的标准上下文特征,比如上下文的类加载器、后置处理器等

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 告诉内部BeanFactory使用上下文的类加载器
        beanFactory.setBeanClassLoader(getClassLoader());
        // 设置Bean表达式解析器
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    
        // 配置上下文回调
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    
        // 在普通工厂中BeanFactory接口不被注册为可解析的类型
        // 消息源注册为Bean
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    
        // 将用于检测内部bean的早期后处理器注册为Applicationlistener。
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    
        // Detect a LoadTimeWeaver and prepare for weaving, if found.
        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            // Set a temporary ClassLoader for type matching.
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }
    
        // 注册默认的环境bean。
        if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
        }
        if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
        }
        if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
        }
    }

    这一步初始化了BeanFactory必须的一些工具。可以理解为:控制飞机的正常运行,需要多个子系统的协作,这里加载必须的子系统。

    > 配置类加载器

    > 配置后置处理器

    > ...

    4. 由上下文子类实现的方法,对bean工厂的后置处理

    这个时候所有bean定义都已加载,但还没有实例化bean。这允许在特定的ApplicationContext实现中注册特殊的BeanPostProcessors

    这一步的体现见上面第0步

    5.☆☆☆调用上下文中注册为bean的工厂后置处理器。

    // 允许自定义修改应用程序上下文的bean定义,调整上下文的底层bean工厂的bean属性值。
    public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
        // 先执行 BeanDefinitionRegistryPostProcessors 
        Set<String> processedBeans = new HashSet<>();
    
        // 如果是BeanDefinitionRegistry接口的实现
        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    
            // 遍历执行Bean定义注册的后置处理器
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryProcessors.add(registryProcessor);
                }
                else {
                    regularPostProcessors.add(postProcessor);
                }
            }
    
            // 第一:不要在这里初始化FactoryBean:我们需要保证所有常规bean未初始化,以便让bean factory后置处理器应用于它们!
            // 第二:将实现PriorityOrdered, Ordered和其他操作的BeanDefinitionRegistryPostProcessors分开。
            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();
    
            // 最后执行所有剩下的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();
            }
    
            // 最最后,调用到目前为止处理的所有处理器的postProcessBeanFactory回调。
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }
    
        else {
            // 不是BeanDefinitionRegistry接口的实现,执行用上下文实例注册的工厂处理器(这个方法就是一个遍历执行的过程)
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }
    
        // 不要在这里初始化FactoryBean:我们需要保证所有常规bean未初始化,以便让bean factory后置处理器应用于它们!
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
        // 将实现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
            }
            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接口的BeanFactoryPostProcessors
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
        // 然后执行实现Ordered接口的BeanFactoryPostProcessors
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
        // 最后执行所有剩下的BeanFactoryPostProcessors
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    
        // 清除缓存的合并bean定义,因为后处理器可能修改了原始的元数据
        beanFactory.clearMetadataCache();
    }

    看起来很多,但是主要分为两部分,而这两部分的逻辑是一样的。

    ⑴ 首先把后置处理器分为BeanDefinitionRegistryPostProcessor(BeanDefinitionRegistry后置处理器)和BeanFactoryPostProcessor(BeanFactory后置处理器)。

      ①将实现PriorityOrdered, Ordered和其他操作的后置处理器分开。

      ②先执行实现PriorityOrdered接口的XXXPostProcessor

      ③然后执行实现Ordered接口的XXXPostProcessor

      ④最后执行所有剩下的XXXPostProcessor

    ⑵ 清除缓存的合并bean定义,因为后处理器可能修改了原始的元数据

    6. ☆☆☆注册拦截bean创建的bean处理器。

    public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
    
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    
        // 注册BeanPostProcessorChecker,它在BeanPostProcessor实例化期间创建bean时记录日志
        // 例如,当一个bean不能被所有的BeanPostProcessor处理时。
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
    
        // 将实现PriorityOrdered, Ordered和其他操作的BeanPostProcessors分开。
        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接口的BeanPostProcessors
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
    
        // 然后注册实现Ordered接口的BeanPostProcessors
        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);
    
        // 最后注册所有剩下的BeanPostProcessors.
        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);
    
        // 最后,重新注册所有的内部BeanPostProcessors.
        sortPostProcessors(internalPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, internalPostProcessors);
    
        // 将后处理器重新注册为ApplicationListener用于检测内部bean,将其移动到处理链的末端(用于获取代理等)。
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

    这部分的套路和执行BeanFactory后置处理器的过程是一样的。

    ⑴ 注册Bean后置处理器

      ① 将实现PriorityOrdered, Ordered和其他操作的BeanPostProcessors分开。

      ②先注册实现PriorityOrdered接口的BeanPostProcessors

      ③然后注册实现Ordered接口的BeanPostProcessors

      ④最后注册所有剩下的BeanPostProcessors.

    ⑵重新注册所有的内部BeanPostProcessors.

    ⑶将后处理器重新注册为ApplicationListener用于检测内部bean,将其移动到处理链的末端(用于获取代理等)。

    7. 为上下文初始化消息源。

    protected void initMessageSource() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        // 如果本地存在messageSource的Bean
        if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
            // 就给属性赋值
            this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
            // Make MessageSource aware of parent MessageSource.
            if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
                HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
                if (hms.getParentMessageSource() == null) {
                    // Only set parent context as parent MessageSource if no parent MessageSource
                    // registered already.
                    hms.setParentMessageSource(getInternalParentMessageSource());
                }
            }
            if (logger.isTraceEnabled()) {
                logger.trace("Using MessageSource [" + this.messageSource + "]");
            }
        }
        else {
            // Use empty MessageSource to be able to accept getMessage calls.
            DelegatingMessageSource dms = new DelegatingMessageSource();
            dms.setParentMessageSource(getInternalParentMessageSource());
            // 都这创建一个默认的
            this.messageSource = dms;
            beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
            if (logger.isTraceEnabled()) {
                logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]");
            }
        }
    }

    8. ☆☆☆为上下文初始化事件广播程序。初始化ApplicationEventMulticaster。如果上下文中没有定义,则使用SimpleApplicationEventMulticaster。

    protected void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = getBeanFactory();
        // 如果本地存在applicationEventMulticaster的Bean
        if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
            // 给applicationEventMulticaster属性赋值
            this.applicationEventMulticaster =
                    beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
            if (logger.isTraceEnabled()) {
                logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
            }
        }
        else {
            // 否则初始化一个SimpleApplicationEventMulticaster,然后注册即可
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
            if (logger.isTraceEnabled()) {
                logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
                        "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
            }
        }
    }

    这部分就是初始化了一个事件广播者

    9. 由上下文的子类实现的方法,初始化其它特殊Bean

    模板方法,可以覆盖该方法以添加特定于上下文的刷新工作。在单例(singleton)实例化之前,在初始化特殊bean时调用。

    这一步的体现见上面第0步

    10. ☆☆☆检查监听器bean并注册它们。

    protected void registerListeners() {
        // 首先注册静态指定的监听器。
        for (ApplicationListener<?> listener : getApplicationListeners()) {
            getApplicationEventMulticaster().addApplicationListener(listener);
        }
    
        // 不要在这里初始化factorybean:我们需要保证所有常规bean未初始化,以便让后处理器应用于它们!
        String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
        for (String listenerBeanName : listenerBeanNames) {
            getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }
    
        // 发布早期的应用事件,到此为止我们已经有了一个广播者
        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
                getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }
    }

    这里完成了两个事情:

    > 注册应用程序监听器

    > 发布早期事件(观察者模式的经典体现)

    11. ☆☆☆实例化所有剩余的(非懒加载)单例。

     完成上下文bean工厂的初始化,初始化所有剩余的单例bean。

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // 为此上下文初始化转换服务(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));
        }
    
        // 注册一个默认的嵌入式值解析器(主要用于解析注释属性值),如果之前没有注册任何bean后置处理器
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
        }
    
        // 尽早初始化LoadTimeWeaverAware bean,以便尽早注册它们的转换器。
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }
    
        // 停止使用临时类加载器进行类型匹配。
        beanFactory.setTempClassLoader(null);
    
        // 允许缓存所有的bean定义元数据,不期望有进一步的更改。
        beanFactory.freezeConfiguration();
    
        // 实例化所有剩余的(非懒加载)单例。
        beanFactory.preInstantiateSingletons();
    }

    这一步干的工作比较多:

    > 为上下文初始化转换服务

    > 注册一个默认的嵌入式值解析器(主要用于解析注释属性值)

    > 停止使用临时类加载器进行类型匹配。

    > 允许缓存所有的bean定义元数据,不期望有进一步的更改。

    > 实例化所有剩余的(非懒加载)单例。

    关于preInstantiateSingletons的执行过程,实际上就是getBean的过程了,这部分上一篇文章做了解读。

    12. ☆☆☆最后一步:发布相应的事件。

    protected void finishRefresh() {
        // 清除上下文级别的资源缓存(比如扫描的ASM元数据)。
        clearResourceCaches();
        // 为此上下文初始化生命周期处理器。
        initLifecycleProcessor();
        // 将生命周期处理器的running标志位设置为true
        getLifecycleProcessor().onRefresh();
        // 发布最终事件。
        publishEvent(new ContextRefreshedEvent(this));
        // Participate in LiveBeansView MBean, if active.
        LiveBeansView.registerApplicationContext(this);
    }
    
    // 看一下ContextRefreshedEvent
    public void publishEvent(ApplicationEvent event) {
        publishEvent(event, null);
    }
    
    protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
        Assert.notNull(event, "Event must not be null");
        // Decorate event as an ApplicationEvent if necessary
        ApplicationEvent applicationEvent;
        if (event instanceof ApplicationEvent) {
            applicationEvent = (ApplicationEvent) event;
        }
        else {
            applicationEvent = new PayloadApplicationEvent<>(this, event);
            if (eventType == null) {
                eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
            }
        }
        // 如果可能的话,现在就广播;或者等广播可用的时候立即广播。
        if (this.earlyApplicationEvents != null) {
            this.earlyApplicationEvents.add(applicationEvent);
        }
        else {
            // 获取事件广播者,异步广播事件给对应的Listener
            getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
        }
        // 通过父上下文发布事件
        if (this.parent != null) {
            if (this.parent instanceof AbstractApplicationContext) {
                ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
            }
            else {
                this.parent.publishEvent(event);
            }
        }
    }

    它是怎么广播给监听者的呢?

    public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
        ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
        Executor executor = getTaskExecutor();
        // 遍历应用程序监听器
        for (ApplicationListener<?> listener : getApplicationListeners(event, type)) {
            // 如果指定了executor,就走异步处理
            if (executor != null) {
                executor.execute(() -> invokeListener(listener, event));
            }
            else {
                invokeListener(listener, event);
            }
        }
    }
    
    protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
        ErrorHandler errorHandler = getErrorHandler();
        if (errorHandler != null) {
            try {
                // 执行Listener,准确来说是监听器的【收听】方法
                doInvokeListener(listener, event);
            }
            catch (Throwable err) {
                errorHandler.handleError(err);
            }
        }
        else {
            doInvokeListener(listener, event);
        }
    }
    
    private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
        try {
            // 这里调用ApplicationListener接口唯一的方法,也就是说,当接收到了事件,监听器要如何做的方法
            listener.onApplicationEvent(event);
        }
        catch (ClassCastException ex) {
            String msg = ex.getMessage();
            if (msg == null || matchesClassCastMessage(msg, event.getClass())) {
                // Possibly a lambda-defined listener which we could not resolve the generic event type for
                // -> let's suppress the exception and just log a debug message.
                Log logger = LogFactory.getLog(getClass());
                if (logger.isTraceEnabled()) {
                    logger.trace("Non-matching event type for listener: " + listener, ex);
                }
            }
            else {
                throw ex;
            }
        }
    }

    这里仅仅扩展一下,看下Spring如何利用【观察者模式】的。

    ----------------------------------------

    这一步显而易见,善后处理:

    > 清除上下文级别的资源缓存

    > 为此上下文初始化生命周期处理器

    > 发布最终事件(上下文已刷新事件)

    13. ☆☆☆销毁已经创建的单例,以避免挂起资源。(异常情况)

    // 如果你看了我上一篇文章,你会知道这段代码以及逻辑在哪里。这里不再赘述
    protected void destroyBeans() {
        getBeanFactory().destroySingletons();
    }

    总结

    宏观想一想,Spring启动的目的是什么?不就是要加载Bean嘛!

    简单来讲:
    1. 把配置解析成规范的Bean定义
    2. 把Bean定义处理并生成Bean实例


    而为了健壮性和扩展性:
    refresh之前:初始化BeanDefinitionReader(Bean定义解析器)
    refresh:
      1. 为上下文刷新做准备:设置其启动开始时间和活动标志以及执行任何属性源的初始化。初始化earlyApplicationListeners和earlyApplicationEvents。
      2. 刷新BeanFactory子容器,返回这个上下文所持有的内部BeanFactory。
      3. 准备bean工厂以供在此上下文中使用。配置工厂的标准上下文特征,比如上下文的类加载器、后置处理器、注册要忽略的依赖接口、注册可解析的依赖。
      4. 【扩展性】由上下文子类实现的方法,对bean工厂的后置处理。(这个时候所有bean定义都已加载,但还没有实例化bean。这允许在特定的ApplicationContext实现中注册特殊的BeanPostProcessors)
      5. 调用已注册的BeanFactoryPostProcessor。针对整个工厂生产出来的BeanDefinition作出修改或者注册。作用于BeanDefinition时期。
      6. 注册BeanPostProcessor。作用于bean,在bean实例化、初始化前后执行。
      7. 初始化事件广播程序。
      8. 【扩展性】模板方法,可以覆盖该方法以添加特定于上下文的刷新工作。在单例(singleton)实例化之前,在初始化特殊bean时调用。
      9. 注册事件监听器。
      10. 实例化所有剩余的单例Bean。
      11. 发布刷新完成事件。(可以联想到Dubbo服务暴露的入口)
      12. 如果以上步骤出现了异常,则要销毁已经创建的单例,以避免挂起资源。

    而Bean的创建呢?

    简单来讲:

    1. 读取Bean定义信息

    2. 根据定义来实例化

    而为了严谨,多加了一些考虑

    1. 确定Bean的原始名称,如果含有&则要去掉。

    2. 先检查单例缓存是否存在。这部分涉及了几个缓存,比如:singletonObjects 和 earlySingletonObjects ,一个存放初始化完毕的Bean,一个存放已经实例化但是还未初始化的Bean,可以用来检测循环依赖。

    3. 从缓存获取的可能是Bean,也可能是FactoryBean。所以这一步根据name特点来判断,如果是个FactoryBean,则调用其getObject方法来返回真正的Bean实例。

    4. 执行创建Bean的逻辑

      【扩展性】执行实例化Bean之前的后置处理器(InstantiationAwareBeanPostProcessor

      - 选取合适的策略来决定如何创建Bean

      - 利用反射实例化后放入BeanWrapper包装类里并返回

      【扩展性】执行实例化Bean之后的后置处理器(InstantiationAwareBeanPostProcessor

      - 根据自动装配模式来判断按照名称还是类型自动装配,具体为:将属性名-属性值映射关系装填到PropertyValues对象来供下面操作使用。

      - 对PropertyValues进行后置处理、检查依赖

      - 给Bean属性赋值

      - 如果Bean实现了Aware接口,则先执行Aware相关方法

      【扩展性】执行初始化Bean之前的后置处理器(BeanPostProcessor

      - 如果实现了 isInitializingBean 接口,则执行其中的 afterPropertiesSet 方法

      - 如果指定了Bean的 initMethod 方法,则执行其初始化方法

      【扩展性】执行初始化Bean之后的后置处理器(BeanPostProcessor

  • 相关阅读:
    flask综合整理1
    flask
    linux
    用户登录权限汇总
    DRF之注册响应分页组件
    MVC 过滤器 构建会员是否登录
    压缩文本、字节或者文件的压缩辅助类-GZipHelper
    MVC 构建图片/文件选择器 参考其它CMS功能
    MVC5+EF6 简易版CMS(非接口) 第四章:使用业务层方法,以及关联表解决方案
    MVC5+EF6 简易版CMS(非接口) 第三章:数据存储和业务处理
  • 原文地址:https://www.cnblogs.com/LUA123/p/12320739.html
Copyright © 2011-2022 走看看