阅读 1513

盘点 SpringIOC : ApplicationContext 一览

总文档 :文章目录
Github : github.com/black-ant

一 . 前言

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

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

看一下整体的逻辑 ApplicationModule.png

二 . ApplicationContext 的初始化

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

ApplicationContextInitializer.png

容器初始化的起点

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 类 ,他们分别为容器配置了相关的属性

applicationInitializersBean.jpg

相关处理

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 的初始化逻辑 , 下面看一下业务逻辑

SpringApplicationContextSystem.jpg

业务处理的核心在于类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             
复制代码

postprocess.jpg

registerBeanPostProcessors


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

复制代码

image-20210501175658179.png

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 的加载流程了.

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

更新记录

  • V20210803 : 优化文本错位问题
文章分类
后端
文章标签