美文网首页Java 程序员spring frameworkJava
盘点 SpringIOC : ApplicationContex

盘点 SpringIOC : ApplicationContex

作者: 马小莫QAQ | 来源:发表于2021-05-06 22:09 被阅读0次

    一 . 前言

    这一篇来详细看看 ApplicationContext 的整体逻辑 , ApplicationContext 整个逻辑中最重要的的一环 , 它具有以下的作用 :

    • 从ListableBeanFactory继承了用于访问应用程序组件的Bean工厂方法的能力
    • 从ResourceLoader接口继承了以通用方式加载文件资源的能力
    • 从ApplicationEventPublisher接口继承了向注册监听器发布事件的能力。
    • 从MessageSource接口继承了解析消息的能力,支持国际化。
    • 单个父上下文可以被整个web应用程序使用,而每个servlet有它自己的独立于任何其他servlet的子上下文。
    • 标准的BeanFactory生命周期功能之外
    • 支持检测和调用ApplicationContextAware以及ResourceLoaderAware , ApplicationEventPublisherAware和MessageSourceAware

    看一下整体的逻辑

    二 . ApplicationContext 的初始化

    容器的初始化主要是 ApplicationContextInitializer , 我们先看一下他的家族体系

    容器初始化的起点

    ApplicationContextInitializer 内部只有一个方法

    I- ApplicationContextInitializer
        M- void initialize(C applicationContext)
    
    // 该方法有三个地方进行了调用
     C- DelegatingApplicationContextInitializer # applyInitializers
     C- ContextLoader # customizeContext
     C- SpringApplication # applyInitializers  
    

    我们要看的主要 C- SpringApplication , 先看看主方法 , 其中run 方法中处理 Context 的有几个地方

    public ConfigurableApplicationContext run(String... args) {
        // ..... 创建 Application Context
        context = createApplicationContext();
        // ..... 容器前置处理 
        prepareContext(context, environment, listeners, applicationArguments, printedBanner);
        // ..... 容器刷新操作
        refreshContext(context);
    }
    

    一个个看这几个节点

    Step 1 : 创建容器

    C01- SpringApplication
        M1_30- createApplicationContext
            ?- 具体可以参考 Application 主流程 , 这里主要是通过 webApplicationType 创建了三个不同 ApplicationContext
            - AnnotationConfigServletWebServerApplicationContext
            - AnnotationConfigReactiveWebServerApplicationContext
            - AnnotationConfigApplicationContext
    
    // M1_30 伪代码
    protected ConfigurableApplicationContext createApplicationContext() {
        Class<?> contextClass = this.applicationContextClass;
        if (contextClass == null) {
            // 根据 type 类型构建
            switch (this.webApplicationType) {
                case SERVLET:
                    contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
                    break;
                case REACTIVE:
                    contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
                    break;
                default:
                    contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
            }
        }
        return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
    }
    

    PS: 通常如果我们使用 SpringMVC , 创建的一般是
    AnnotationConfigServletWebServerApplicationContext

    C01- SpringApplication
        M1_35- prepareContext : 完善容器
            - postProcessApplicationContext : 对 Context 进行设置
            - applyInitializers(context)  初始化容器属性
            - 发布了一个 contextPrepared 监听事件
            - 如果是懒加载 , 添加 BeanFactoryPostProcessor
            - 发布了一个 contextLoaded 监听事件
        M1_37- applyInitializers
            FOR- 循环获取到的所有的 getInitializers  , 执行 initialize
                ?- 这里分别执行了 DelegatingApplicationContextInitializer
        M1_39- postProcessApplicationContext
            - 设置 Context BeanFactory beanName 生成器
                ?- org.springframework.context.annotation.internalConfigurationBeanNameGenerator
            - 设置 ResourceLoader
            - 设置 ClassLoader
            - 设置 Context BeanFactory ConversionService
                ?- ApplicationConversionService
    

    伪代码 ---->

    // M1_35 核心代码
    private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
                SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
            context.setEnvironment(environment);
            postProcessApplicationContext(context);
            // 核心操作 : 初始化容器属性
            applyInitializers(context);
            listeners.contextPrepared(context);
            if (this.logStartupInfo) {
                logStartupInfo(context.getParent() == null);
                logStartupProfileInfo(context);
            }
            // Add boot specific singleton beans
            ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
            beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
            if (printedBanner != null) {
                beanFactory.registerSingleton("springBootBanner", printedBanner);
            }
            if (beanFactory instanceof DefaultListableBeanFactory) {
                ((DefaultListableBeanFactory) beanFactory)
                        .setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
            }
            if (this.lazyInitialization) {
                context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
            }
            // Load the sources
            Set<Object> sources = getAllSources();
            Assert.notEmpty(sources, "Sources must not be empty");
            load(context, sources.toArray(new Object[0]));
            listeners.contextLoaded(context);
    }      
    

    整个代码的核心就在于 applyInitializers :

    // M1_37 伪代码
    protected void applyInitializers(ConfigurableApplicationContext context) {
        // getInitializers -> PS:M1_37_01
        for (ApplicationContextInitializer initializer : getInitializers()) {
                // .... 省略断言操作 , 判断当前的类是否可以 initializer
                initializer.initialize(context);
        }
    }  
    

    可以看到 , 这里 For 循环执行了很多
    ApplicationContextInitializer 类 ,他们分别为容器配置了相关的属性

    相关处理

    C07- DelegatingApplicationContextInitializer
        ?- 根据环境变量配置的context.initializer.classes 配置的 ApplicationContextInitializer 类们,交给它们进行初始化
        I- ApplicationContextInitializer
        I- Ordered 
        M7_01- initialize(ConfigurableApplicationContext context)
            -> 调用 #getInitializerClasses(ConfigurableEnvironment env) 方法,
                ?- 获得环境变量配置的 ApplicationContextInitializer 集合们
            -> 调用 #applyInitializerClasses方法,执行初始化
        M- getInitializerClasses
            -> 获取环境变量配置的属性
            -> 拼装为数组 ,逗号分隔
        M- applyInitializerClasses方法
             P- ConfigurableApplicationContext context
            P- List<Class<?>> initializerClasses
            -> 遍历 initializerClasses , 创建对应的ApplicationContextInitializer , 加入 initializers
            -> 执行 ApplicationContextInitializer  的初始化逻辑
                -> 先排序 , 再执行
        M- initialize(ConfigurableApplicationContext context) 方法
            |- 获取环境变量配置的ApplicationContextInitializer 集合们
            |- 如果非空 , 则进行初始化
        M- getInitializerClasses(ConfigurableEnvironment env)
            |- 获得环境变量配置的属性
            |- 以逗号分隔 ,拼装成List -> classes
            |- Return classes
        M- getInitializerClasses(String className)  
            |- ClassUtils 获取全类名对应的类
        M- applyInitializerClasses
    
    C08- ContextIdApplicationContextInitializer : 负责生成 Spring 容器的编号
        I- ApplicationContextInitializer
        I- Ordered 
        M8_01- initialize(ConfigurableApplicationContext applicationContext)
            -> 调用 #getContextId(ConfigurableApplicationContext applicationContext) 方法,
                ?- 获得(创建) ContextId 对象
            -> 设置到 applicationContext.id 中
            -> 注册到 contextId 到 Spring 容器中
        M- getContextId(ConfigurableApplicationContext applicationContext)
            |- 获取 ApplicationContext -> applicationContext.getParent();
            B-> ApplicationContext 包含 ContextId 类  
                |- 直接返回 -> parent.getBean(ContextId.class).createChildId()
            E-> 否则构建新 ContextId
                |- new ContextId()->
                    P-getApplicationId(applicationContext.getEnvironment())
    
    C09- ConfigurationWarningsApplicationContextInitializer : 用于检查配置,报告错误的配置
        I- ApplicationContextInitializer 
        M9_01- initialize(ConfigurableApplicationContext context)
            - 注册 ConfigurationWarningsPostProcessor 到 Spring 容器中
    
    C10- RSocketPortInfoApplicationContextInitializer : socket 连接配置
        M10_01- initialize(ConfigurableApplicationContext applicationContext)
            - addApplicationListener : 添加了一个 Listener
    
    C11- ServerPortInfoApplicationContextInitializer
        ?- 监听 EmbeddedServletContainerInitializedEvent 类型的事件,然后将内嵌的 Web 服务器使用的端口给设置到 ApplicationContext 中            
        I- ApplicationContextInitializer
        I- ApplicationListener 
        M11_01- initialize
            |- 将自身作为一个 ApplicationListener 监听器,添加到 Spring 容器中
        M- onApplicationEvent
            ?- 当监听到 WebServerInitializedEvent 事件,进行触发
            |- 获取属性名 -> local + name + port 拼接
            |- 设置端口到 environment 的 PropertyName 中
        M- getName(WebServerApplicationContext context)
            |- Context.getServerNamespace()
        M- setPortProperty(ApplicationContext context, String propertyName, int port)
            |- 设置端口到enviroment 的 propertyName 中
            |- 如果有父容器 ,则继续设置
        M-  setPortProperty(ConfigurableEnvironment ,  propertyName,  port)
            |- 获取 server.ports 属性对应的值
            B- 如果source 为 null ,则创建MapPropertySource
    
    C12- ConditionEvaluationReportLoggingListener
        M12_01- initialize(ConfigurableApplicationContext applicationContext) 
             - 同样加入了一个 ConditionEvaluationReportListener
    
    C13- SharedMetadataReaderFactoryContextInitializer
        ?-  它会创建一个用于在 ConfigurationClassPostProcessor 和 Spring Boot 间共享的 CachingMetadataReaderFactory Bean 对象
        I- ApplicationContextInitializer
        I- Ordered 
    

    额外操作 ComponentScanPackageCheck

    C- ComponentScanPackageCheck
        I- Check 
        M- getWarning
            -> 调用 #getComponentScanningPackages(BeanDefinitionRegistry registry) 方法,
                ?- 获得要扫描的包
                -> 扫描的包的集合
                ->  names = registry.getBeanDefinitionNames(); // 获得所有 BeanDefinition 的名字们
                FOR -> names
                    -> 如果是 AnnotatedBeanDefinition , 如果有 @ComponentScan 注解,则添加到 packages 中
            -> getProblematicPackages(Set<String> scannedPackages) 方法,获得要扫描的包中
                    -> 就是判断 scannedPackages 哪些在 PROBLEM_PACKAGES 中
                    -> 如果是在 PROBLEM_PACKAGES 中 ,添加到 problemPackage
    

    三 . ApplicationContext 的业务逻辑

    上面看完了 ApplicationContext 的初始化逻辑 , 下面看一下业务逻辑

    业务处理的核心在于类 AbstractApplicationContext , SpringBoot 启动时 , 会在该类中处理部分 Context 的逻辑

    C50- AbstractApplicationContext
        // 支持的ApplicationContext 功能
        M- void setId(String id)
        M- void setDisplayName(String displayName)   
        M- void setEnvironment(ConfigurableEnvironment environment)
        M- ConfigurableEnvironment createEnvironment()
            // 允许发布事件 
        M- void publishEvent(ApplicationEvent event)
        M- void publishEvent(Object event)
        M- void publishEvent(Object event, @Nullable ResolvableType eventType)
            // 主要的get方法
        M- ApplicationEventMulticaster getApplicationEventMulticaster()
        M- LifecycleProcessor getLifecycleProcessor()
        M- ResourcePatternResolver getResourcePatternResolver()
            // 初始化操作
        M50_20- void initMessageSource()
        M50_21- void initApplicationEventMulticaster()
        M50_22- void initLifecycleProcessor()
        M50_23- void initApplicationEventMulticaster()
            M50_24- void registerListeners()
        M50_27- void initPropertySources()
            // 主要操作
            M- void resetCommonCaches()
            M- void registerShutdownHook()
            M- void destroy()
            M- void close()
            M50_25- void doClose()
            M- void destroyBeans()
            // 核心方法详解
        M50_2- void refresh() 
        M50_10- void setParent(@Nullable ApplicationContext parent)
        M50_11- void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor)
        M50_12- void addApplicationListener(ApplicationListener<?> listener)
        M50_13- void prepareRefresh()
        M50_14- void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory)
        M50_15- void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory)
        M50_16- void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)
        M50_17- void finishRefresh()
        M50_18- void cancelRefresh(BeansException ex)
        M50_30- void start()
        M50_31- void stop()
        M50_13- boolean isRunning()
        M50_32- void postProcessBeanFactory() 
        M50_33- void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory)
            // 获取 Bean 操作
        M- Object getBean(String name)
        M- <T> T getBean(String name, Class<T> requiredType)
        M- Object getBean(String name, Object... args)
        M- <T> T getBean(Class<T> requiredType)
        M- <T> T getBean(Class<T> requiredType, Object... args)
        M- <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType)
        M- <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType)
        M- <T> Map<String, T> getBeansOfType(@Nullable Class<T> type)
        M- String[] getBeanNamesForType(ResolvableType type)
        M- String[] getBeanDefinitionNames()
        M- <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
        M- Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType)
        M- String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType)
        M- boolean containsLocalBean(String name)
             // 判断 Bean
        M- boolean containsBean(String name)
        M- boolean isSingleton(String name)
        M- boolean isPrototype(String name)
        M- boolean isTypeMatch(String name, ResolvableType typeToMatch)
        M- boolean containsBeanDefinition(String beanName)
             // 其他操作
        M- String getMessage(....)
        M- MessageSource getMessageSource()
    

    我们依次来看一下相关的方法功能 :

    Module 1 : 标识属性的作用 , 我们常用的属性通常Id 和 Environment

    M- void setId(String id)
        ?- ContextIdApplicationContextInitializer # initialize 中进行设置
        ?- 该 ID 会被用于设置 beanFactory SerializationId 
    M- void setDisplayName(String displayName) 
    M- void setEnvironment(ConfigurableEnvironment environment)
        ?- SpringApplication # prepareContext 中进行设置
    M- ConfigurableEnvironment createEnvironment()
        ?- PS : AnnotatedBeanDefinitionReader getOrCreateEnvironment 中会直接创建
    

    Module 2 : 事件的发布

    M- void publishEvent(ApplicationEvent event)
    M- void publishEvent(Object event)
    M- void publishEvent(Object event, @Nullable ResolvableType eventType)      
        ?- 上面2个最终都会调用该方法
        - 传入的 event 为 ApplicationEvent 则直接使用 , 不是则转换为  PayloadApplicationEvent
        - 如果开启了 earlyApplicationEvents , 则加入 ,否则通过 ApplicationEventMulticaster 发布
            ?- ApplicationEventMulticaster用来通知所有的观察者对象,属于观察者设计模式中的Subject对象
        - 父容器不为空 , 则parent.publishEvent
    

    Module 3 : 主要的get方法

    M- ApplicationEventMulticaster getApplicationEventMulticaster() : 获取多播器
    M- LifecycleProcessor getLifecycleProcessor() : 返回上下文使用的内部LifecycleProcessor
        ?- LifecycleProcessor : 用于在ApplicationContext中处理生命周期bean的策略接口
    M- ResourcePatternResolver getResourcePatternResolver()
        ?- 用于将 location (例如 ant location)解析为资源对象的策略接口
    

    Module 4 : 初始化操作

    M50_20- void initMessageSource() : 初始化MessageSource
        - 获取 ConfigurableListableBeanFactory , 判断其中是否包含 messageSource
        TRUE- 获取 MessageSource , 并且设置 ParentMessageSource
            ?- hms.setParentMessageSource(getInternalParentMessageSource())
        FALSE- 创建一个 DelegatingMessageSource , 设置 ParentMessageSource
            - 将当前 MessageSource 设置到 beanFactory 中
                    ?- beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource)
    
    M- void initApplicationEventMulticaster() : 初始化ApplicationEventMulticaster
        ?- ApplicationEventMulticaster : 管理许多ApplicationListener对象并向它们发布事件
        ?- 如果上下文中没有定义,则使用SimpleApplicationEventMulticaster
        - 获取 ConfigurableListableBeanFactory , 判断是否包含 applicationEventMulticaster
            TRUE- 包含则从 beanFactory 中获取
            FALSE- 构建一个 SimpleApplicationEventMulticaster , 并且 registerSingleton 注册
    
    M- void initLifecycleProcessor()
        - 同理 , 从 ConfigurableListableBeanFactory 中判断是否存在 lifecycleProcessor
        - 存在则获取 , 不存在则创建一个  DefaultLifecycleProcessor
    
    M- void initApplicationEventMulticaster()
        - 同理 , 从 ConfigurableListableBeanFactory 中判断是否存在 applicationEventMulticaster
        - 存在则获取 , 不存在则创建一个  SimpleApplicationEventMulticaster
    
    M50_24- void registerListeners()   
        - 获取 当前 Context Set<ApplicationListener<?>> , 添加到 ApplicationEventMulticaster 中
        - 通过 ApplicationListener 类型获取( getBeanNamesForType) , 添加到 ApplicationEventMulticaster 中 
        - 选择合适的 listener 处理当前 earlyApplicationEvents
    

    Module 5 : 主要操作

    M- void resetCommonCaches() : 重新清空缓存
        ?- 包括 ReflectionUtils / AnnotationUtils / ResolvableType / CachedIntrospectionResults
    M- void registerShutdownHook()
    M- void destroy()
        - 调用 close
    M- void close()
        - 调用 doClose
    M50_25 - void doClose() :执行最终的逻辑
    M- void destroyBeans() 
    

    M50_25 伪代码

    protected void doClose() {
            // Check whether an actual close attempt is necessary...
            if (this.active.get() && this.closed.compareAndSet(false, true)) {
                LiveBeansView.unregisterApplicationContext(this);
    
                publishEvent(new ContextClosedEvent(this));
                // 停止所有Lifecycle bean,以避免单个销毁期间的延迟
                if (this.lifecycleProcessor != null) {
                        this.lifecycleProcessor.onClose();
                }
    
                // 销毁上下文BeanFactory中所有缓存的单例
                destroyBeans();
    
                // 关闭此上下文本身的状态.
                closeBeanFactory();
    
                // 如果子类愿意的话,让它们做一些最后的清理工作
                onClose();
    
                // 将本地应用程序监听器重置为预刷新状态.
                if (this.earlyApplicationListeners != null) {
                    this.applicationListeners.clear();
                    this.applicationListeners.addAll(this.earlyApplicationListeners);
                }
    
                // 切换 Active 状态.
                this.active.set(false);
            }
        }  
    

    最重要的核心逻辑系列

    // 核心方法详解
        M50_2- void refresh() : 刷新容器主流程
            - 调用 prepareRefresh -> M50_13
            - 获取 ConfigurableListableBeanFactory , 并且调用 prepareBeanFactory 进行前置处理 -> M50_14
            - 调用 postProcessBeanFactory -> M50_32
            - 调用 registerBeanPostProcessors -> M50_33
            - 调用 initMessageSource -> M50_20
            - 调用 initApplicationEventMulticaster -> M50_21
            - 调用 onRefresh -> 该方法需要子类实现
            - 调用 registerListeners -> M50_24
            - 调用 finishBeanFactoryInitialization 完成 BeanFactory 初始化流程 -> M50_16
            - 调用 finishRefresh -> finishRefresh M50_17
        M50_10- void setParent(@Nullable ApplicationContext parent) : 设置父容器
        M50_11- void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor)
        M50_12- void addApplicationListener(ApplicationListener<?> listener) : 添加事件监听器
        M50_13- void prepareRefresh() : 前置处理
            - 前置处理 , 首先会设置状态 : close active
            - 调用 initPropertySources (空实现)
            - 校验 enviroment validateRequiredProperties
            - 如果 earlyApplicationListeners 为空 , 则将当前 applicationListeners 全部加入
            - 如果 earlyApplicationListeners 存在 , 则将 applicationListeners 替换为 earlyApplicationListeners 的监听器
            - 重置 earlyApplicationEvents
        M50_14- void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory)
            - 为当前 beanFactory 设置各类属性 
        M50_15- void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory)
            ?- 方法中做了2类事
             - 调用 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors   
             - 如果存在 Bean , 为beanFactory 添加 BeanPostProcessor + TempClassLoader
        M50_16- void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)
             - 如果存在 ConversionService , 则为 BeanFactory 设置 ConversionService
             - 视情况添加 EmbeddedValueResolver
             - 尽早始化LoadTimeWeaverAware bean,以允许尽早注册它们的转换器   
                ?- 通过触发 getBean(weaverAwareName) 获取
             - 停止使用临时ClassLoader进行类型匹配
             - 允许缓存所有bean定义元数据
             - 实例化所有剩余的(非lazy-init)单例
        M50_17- void finishRefresh()
             - 清除上下文级资源缓存(例如扫描ASM元数据)
             - 初始化此上下文的生命周期处理器
             - 首先将刷新传播到生命周期处理器
             - 发布最终事件
             - 将当前 ApplicationContext 注册到 LiveBeansView
        M50_18- void cancelRefresh(BeansException ex)
             - 修改状态  -> this.active.set(false
        M50_30- void start()
             - 启动生命周期管理 getLifecycleProcessor().start();     
             - 发布一个 publishEvent 事件 ContextStartedEvent
        M50_31- void stop()
             - 启动生命周期管理 getLifecycleProcessor().stop()
             - 发布事件  ContextStoppedEvent     
        M50_13- boolean isRunning()
            - 判断 lifecycleProcessor.isRunning()                  
        M50_32- void postProcessBeanFactory() 
            - 空实现 , 在应用程序上下文的标准初始化之后修改其内部bean工厂
            - 该方法会在子类中处理
        M50_33- void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory)
            - 调用 PostProcessorRegistrationDelegate # registerBeanPostProcessors 方法
                ?-> 
        M50_27- void initPropertySources()
    

    M50_2 伪代码 , 回头继续看一下这个流程

        @Override
        public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
                // 准备此上下文以进行刷新 -> M50_13
                prepareRefresh();
    
                // Tell the subclass to refresh the internal bean factory.
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
                // 告诉子类刷新内部bean工厂
                prepareBeanFactory(beanFactory);
    
                try {
                    // 允许在上下文子类中对bean工厂进行后处理
                    postProcessBeanFactory(beanFactory);
    
                    // 调用在上下文中注册为bean的工厂处理器
                    // IOC 的主要逻辑就在其中
                    invokeBeanFactoryPostProcessors(beanFactory);
    
                    // 注册拦截Bean创建的Bean处理器
                    registerBeanPostProcessors(beanFactory);
    
                    // 初始化此上下文的消息源
                    initMessageSource();
    
                    // 初始化此上下文的事件多主控器.
                    initApplicationEventMulticaster();
    
                    // 初始化特定上下文子类中的其他特殊bean.
                    onRefresh();
    
                    // 检查侦听器bean并注册它们.
                    registerListeners();
    
                    // 实例化所有剩余的(非lazy-init)单例.
                    finishBeanFactoryInitialization(beanFactory);
    
                    //最后一步:发布相应的事件
                    finishRefresh();
                }catch (BeansException ex) {
    
                    // 销毁已创建的单件以避免资源悬空
                    destroyBeans();
    
                    // 重置“活动”标志.
                    cancelRefresh(ex);
    
                    // 将异常传播到调用方.
                    throw ex;
                }
    
                finally {
                    // Reset common introspection caches in Spring's core, since we
                    // might not ever need metadata for singleton beans anymore...
                    resetCommonCaches();
                }
            }
        }
    

    BeanPostProcessors 流程比较多 , 足够开个单章了,这里就不说了

    作用 : 允许对应用程序上下文的bean定义进行自定义修改 , 可以调整上下文的基础bean工厂的bean属性值
    特点 : BeanFactoryPostProcessor可以与bean定义交互并修改它们,但绝不会与bean实例交互

    此处主要调用
    ConfigurationClassPostProcessor , 其中处理 processConfigBeanDefinitions

    C52- PostProcessorRegistrationDelegate
        M52_01- invokeBeanFactoryPostProcessors
            - 调用给定的BeanFactoryPostProcessor bean
        M52_02- registerBeanPostProcessors
            - 注册给定的BeanPostProcessor bean             
    

    registerBeanPostProcessors

    
    private static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
        for (BeanPostProcessor postProcessor : postProcessors) {
            beanFactory.addBeanPostProcessor(postProcessor);
        }
    }
    

    DefaultLifecycleProcessor 流程

    
    C53- DefaultLifecycleProcessor
        ?- 用于在ApplicationContext中处理生命周期bean的策略接口        
        M53_01- startBeans  
            -                    
        M53_02- stopBeans
        M53_03- doStart
        M53_04- doStop                         
        M53_05- getLifecycleBeans() : 检索所有适用的生命周期bean                  
    
    • Lifecycle 接口 :

    • 定义启动/停止生命周期控制方法的公共接口

    • 可以是 Bean 和容器

    • 当ApplicationContext自身启动和停止时,它将自动调用上下文内所有生命周期的实现

    • LifecycleProcessor 接口 :

    • LifecycleProcessor 负责管理ApplicationContext生命周期

    • LifecycleProcessor自身扩展了Lifecycle接口。它也增加了两个其他的方法来与上下文交互,使得可以刷新和关闭

    • LifecycleProcessor的onRefresh与onClose是比较重要的方法

    • onRefresh作用是容器启动成功

    • onClose是只应用要关闭的时候

    • DefaultLifecycleProcessor

    • 默认LifecycleProcessor实现,主要是负责所有的LifecycleProcessor实现执行

    • DefaultLifecycleProcessor是LifecycleProcessor的代理对象。

    M50_14 : 伪代码

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
            // Tell the internal bean factory to use the context's class loader etc.
            beanFactory.setBeanClassLoader(getClassLoader());
            beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
            beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    
            // Configure the bean factory with context callbacks.
            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 interface not registered as resolvable type in a plain factory.
            // MessageSource registered (and found for autowiring) as a bean.
            beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
            beanFactory.registerResolvableDependency(ResourceLoader.class, this);
            beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
            beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    
            // Register early post-processor for detecting inner beans as ApplicationListeners.
            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()));
            }
    
            // Register default environment beans.
            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());
            }
        }
    

    M50_16 finishBeanFactoryInitialization

    M50_16- void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)
             - 
             - 视情况添加 EmbeddedValueResolver
             - 尽早始化LoadTimeWeaverAware bean,以允许尽早注册它们的转换器   
                ?- 通过触发 getBean(weaverAwareName) 获取
             - 停止使用临时ClassLoader进行类型匹配
             - 允许缓存所有bean定义元数据
             - 实例化所有剩余的(非lazy-init)单例
    
        protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
            // 如果存在 ConversionService , 则为 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));
            }
    
            // 视情况添加 EmbeddedValueResolver
            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) 获取
                getBean(weaverAwareName);
            }
    
            // 停止使用临时ClassLoader进行类型匹配
            beanFactory.setTempClassLoader(null);
    
            // 允许缓存所有bean定义元数据
            beanFactory.freezeConfiguration();
    
            // 实例化所有剩余的(非lazy-init)单例
            beanFactory.preInstantiateSingletons();
        }
    

    总结

    整个 ApplicationContext 流程就完成了 , 这个流程完结后 , 就可以开始 IOC Bean 的加载流程了.

    写着真累 , 具体逻辑看图应该就差不多了

    作者:AntBlack
    链接:https://juejin.cn/post/6957341008312926215
    来源:掘金

    相关文章

      网友评论

        本文标题:盘点 SpringIOC : ApplicationContex

        本文链接:https://www.haomeiwen.com/subject/vdrjdltx.html