草庐IT

Spring之SpringContext

folyh 2023-04-09 原文

一、概述

1.Spring Context概念

创建上下文并将BeanPostProcessor加载到spring

2.Spring Application Context概念

Spring通过应用上下文(Application Context)装载bean的定义并把它们组装起来。Spring应用上下文全权负责对象的创建和组装。

3. 关系

(1)Spring Context 模块核心是Spring Context

(2)Spring Context 核心是Spring Application Context

(3)Spring Application Context 的核心方法是 AbstractApplicationContext

二、AbstractApplicationContext之刷新源码分析

1. 基础源码

高效记忆:Spring应用文刷新 — 刷机

(1)手机系统太卡了于是自己刷机。首先 准备刷机环境 (准备刷新上下文环境),准备好后老系统 初始化并加载 定义信息(初始化BeanFactory,并加载bean definitions信息)

(2)然后进行系统 配置 并(对beanFacotry进行配置)开始系统 激活 并提交过程(激活BeanFactoryPostProcessors)

(3)再进行验证码 注册 并提交过程(注册BeanPostProcessors),注册后新系统 初始化信息资源、广播 且注册监听器(初始化MessageSource、初始化事件广播器、注册事件监听器)

(4)最后系统 热加载弹粒 并(构造热加载单例bean)完成刷机 (完成刷新过程,通知生命周期处理器),如果刷机 错误销户并修改 激活标识(销毁bean、修改active标识)

	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();   // #1 准备刷新上下文环境

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // #2 初始化BeanFactory,并加载bean definitions信息

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);    // #3 对beanFacotry进行配置

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);    // #4  提供给子类扩展的预留方法

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);   // #5 激活BeanFactoryPostProcessors

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);    // #6 注册BeanPostProcessors

				// Initialize message source for this context.
				initMessageSource();    // #7 初始化MessageSource

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();  // #8 初始化事件广播器

				// Initialize other special beans in specific context subclasses.
				onRefresh();    // #9 提供给子类初始化其他的Bean

				// Check for listener beans and register them.
				registerListeners();    // #10 注册事件监听器

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);   // #11 构造热加载单例bean

				// Last step: publish corresponding event.
				finishRefresh();    // #12 完成刷新过程,通知生命周期处理器
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans(); // #13 出错了,销毁bean

				// Reset 'active' flag.
				cancelRefresh(ex);  // #14 出错了,修改active标识

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

2.初始化并加载 obtainFreshBeanFactory

AbstractApplicationContext—obtainFreshBeanFactory ----> AbstractRefreshableApplicationContext—refreshBeanFactory

protected final void refreshBeanFactory() throws BeansException {
    if (hasBeanFactory()) { // #1 如果已存在BeanFactory,销毁原来的BeanFactory
        destroyBeans();
        closeBeanFactory();
    }
    try {
        DefaultListableBeanFactory beanFactory = createBeanFactory();   // #2 创建DefaultListableBeanFactory
        beanFactory.setSerializationId(getId());
        customizeBeanFactory(beanFactory);
        // #3 加载bean definitions信息,loadBeanDefinitions是抽象方法,不同实现类会从不同的配置中获取bean definitions信息,
        // 如AnnotationConfigWebApplicationContext,XmlWebApplicationContext。
        loadBeanDefinitions(beanFactory);   
        synchronized (this.beanFactoryMonitor) {
            this.beanFactory = beanFactory;
        }
    }
    catch (IOException ex) {
        throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    }
}

3.激活 BeanFactoryPostProcessors

(1)BeanFactoryPostProcessor是spring提供的扩展接口,可以通过BeanFactoryPostProcessor对beanFactory进行自定义处理,如修改其他BeanDefinition的配置。

(2)BeanFactoryPostProcessor可以调整beanFactory,甚至修改BeanDefinition,如CustomEditorConfigurer,将用户定义的PropertyEditor注册到beanFactory中,以便后续使用。

(3)BeanDefinitionRegistryPostProcessor可以注册新的BeanDefinition,如ConfigurationClassPostProcessor,是实现springboot很关键的类

AbstractApplicationContext—invokeBeanFactoryPostProcessors ----> PostProcessorRegistrationDelegate—invokeBeanFactoryPostProcessors

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

    Set<String> processedBeans = new HashSet<String>();
	// #1 如果beanFactory是BeanDefinitionRegistry,需要处理BeanFactoryPostProcessors,
	// BeanDefinitionRegistryPostProcessor,否则只处理BeanFactoryPostProcessors
    if (beanFactory instanceof BeanDefinitionRegistry) {    
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
        List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
                new LinkedList<BeanDefinitionRegistryPostProcessor>();
		// #2 方法参数beanFactoryPostProcessors是AbstractApplicationContext---beanFactoryPostProcessors属性,
		// 用户可以通过AbstractApplicationContext---addBeanFactoryPostProcessor方法添加BeanFactoryPostProcessor。这里对beanFactoryPostProcessors参数进行分类
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {              if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                BeanDefinitionRegistryPostProcessor registryPostProcessor =
                        (BeanDefinitionRegistryPostProcessor) postProcessor;
                registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
                registryPostProcessors.add(registryPostProcessor);
            }
            else {
                regularPostProcessors.add(postProcessor);
            }
        }

		// #3 获取beanFactory已经存在的BeanDefinitionRegistryPostProcessor,这里并没有直接构建BeanDefinitionRegistryPostProcessor,而且通过beanName获取
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);    

        // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
        List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
        for (String ppName : postProcessorNames) {
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); 
                // #4 获取实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor,添加到priorityOrderedPostProcessors     
                processedBeans.add(ppName);
            }
        }
        // #5 对priorityOrderedPostProcessors排序
        sortPostProcessors(beanFactory, priorityOrderedPostProcessors);     
        // #6 排序结果添加到registryPostProcessors
        registryPostProcessors.addAll(priorityOrderedPostProcessors);   
         // #7 调用BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
        invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);   

        // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
        for (String ppName : postProcessorNames) {
        	// #8 处理实现了Ordered的BeanDefinitionRegistryPostProcessor
            if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {   
                orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                processedBeans.add(ppName);
            }
        }
        sortPostProcessors(beanFactory, orderedPostProcessors); 
        registryPostProcessors.addAll(orderedPostProcessors);
        invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);    

        // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
        boolean reiterate = true;
        while (reiterate) {
            reiterate = false;
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
            	// #9 处理剩余的BeanDefinitionRegistryPostProcessor
                if (!processedBeans.contains(ppName)) { 
                    BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
                    registryPostProcessors.add(pp);
                    processedBeans.add(ppName);
                    pp.postProcessBeanDefinitionRegistry(registry);
                    reiterate = true;
                }
            }
        }

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

    ...
}

4.初始化事件广播 initApplicationEventMulticaster

4.1 Spring事件体系包括三个组件:

ApplicationEvent事件,ApplicationListener事件监听器,ApplicationEventMulticaster事件广播器。

4.2 事件广播器负责管理事件监听器,并将事件广播给监听器。

AbstractApplicationContext — initApplicationEventMulticaster

rotected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        this.applicationEventMulticaster =
                beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);    //#1 使用用户定义的事件广播器
        if (logger.isDebugEnabled()) {
            logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
        }
    }
    else {
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);   //#2 使用默认的事件广播器
        if (logger.isDebugEnabled()) {
            logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
                    APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
                    "': using default [" + this.applicationEventMulticaster + "]");
        }
    }
}

4.3 spring事件

(1)spring提供了context start,stop,close,refresh等事件,ApplicationListener — onApplicationEvent负责处理spring中的事件。

(2)我们可以通过实现ApplicationListener接口自行处理事件,也可以通过PublishListener自定义事件监听器。

使用默认的事件广播器 AbstractApplicationContexton — publishEvent ----> SimpleApplicationEventMulticaster — multicastEvent

public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
    ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
        Executor executor = getTaskExecutor();  // #1 如果配置了Executor,使用Executor多线程处理
        if (executor != null) {
            executor.execute(new Runnable() {
                public void run() {
                    invokeListener(listener, event);
                }
            });
        }
        else {
            invokeListener(listener, event);    // #2 否则单线程处理
        }
    }
}

5.注册事件监听器

AbstractApplicationContext — registerListeners将初始化事件监听器ApplicationListener,并绑定到事件广播器上。

protected void registerListeners() {
    for (ApplicationListener<?> listener : getApplicationListeners()) { // #1 getApplicationListeners()获取的是AbstractApplicationContext --- applicationListeners,用户可以通过AbstractApplicationContext --- addApplicationListener添加事件监听器AbstractApplicationContext#applicationListeners注册到applicationEventMulticaster
        getApplicationEventMulticaster().addApplicationListener(listener);
    }

    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);   // #2 将上下文中的ApplicationListener注册到applicationEventMulticaster
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;   // #3 发布在此之前已发生的事件
    this.earlyApplicationEvents = null;
    if (earlyEventsToProcess != null) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

6.构造热加载单例bean

AbstractApplicationContext — finishBeanFactoryInitialization

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // Initialize conversion service for this context.
    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));    //#1 初始化ConversionService,后面注入属性要使用
    }

    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(new StringValueResolver() {    //#2 初始化StringValueResolver,用于解析bean属性引用的properties配置
            @Override
            public String resolveStringValue(String strVal) {
                return getEnvironment().resolvePlaceholders(strVal);
            }
        });
    }

    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);   //#3 初始化LoadTimeWeaverAware
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }

    beanFactory.setTempClassLoader(null);

    beanFactory.freezeConfiguration();

    // Instantiate all remaining (non-lazy-init) singletons.
    beanFactory.preInstantiateSingletons(); //#4 构造热加载单例bean
}

AbstractApplicationContext — preInstantiateSingletons

public void preInstantiateSingletons() throws BeansException {
    ...

    List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

    for (String beanName : beanNames) {
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { // #1 判断是否为非抽象类的热加载单例bean
            if (isFactoryBean(beanName)) {
                final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                            @Override
                            public Boolean run() {
                                return ((SmartFactoryBean<?>) factory).isEagerInit();
                            }
                        }, getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
            }
            else {
                getBean(beanName);  // #2 构造bean:如果非FactoryBean,构造bean。如果FactoryBean并且FactoryBean.isEagerInit为true,构造bean。
            }
        }
    }
    ...
}

7. 完成刷新 finishRefresh

LifecycleProcessor也是spring提供的扩展点, 通过它可以在spring content start,stop,onRefresh等时刻自定义一些额外操作

protected void finishRefresh() {
    // Initialize lifecycle processor for this context.
    initLifecycleProcessor();   // #1 初始化LifecycleProcessor

    // Propagate refresh to lifecycle processor first.
    getLifecycleProcessor().onRefresh();    // #2 调用LifecycleProcessor#onRefresh()方法

    // Publish the final event.
    publishEvent(new ContextRefreshedEvent(this));  // #3 发布事件

    // Participate in LiveBeansView MBean, if active.
    LiveBeansView.registerApplicationContext(this);
}

参考链接1


随心所往,看见未来。Follow your heart,see light!

*欢迎点赞、关注、留言,收藏及转发,一起学习、交流!

有关Spring之SpringContext的更多相关文章

  1. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  2. spring.profiles.active和spring.profiles.include的使用及区别说明 - 2

    转自:spring.profiles.active和spring.profiles.include的使用及区别说明下文笔者讲述spring.profiles.active和spring.profiles.include的区别简介说明,如下所示我们都知道,在日常开发中,开发|测试|生产环境都拥有不同的配置信息如:jdbc地址、ip、端口等此时为了避免每次都修改全部信息,我们则可以采用以上的属性处理此类异常spring.profiles.active属性例:配置文件,可使用以下方式定义application-${profile}.properties开发环境配置文件:application-dev

  3. ruby-on-rails - Spring 不起作用。 [未初始化常量 Spring::SID::DL] - 2

    我无法运行Spring。这是错误日志。myid-no-MacBook-Pro:myid$spring/Users/myid/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/spring-0.0.10/lib/spring/sid.rb:17:in`fiddle_func':uninitializedconstantSpring::SID::DL(NameError)from/Users/myid/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/spring-0.0.10/li

  4. 【云原生】SpringCloud-Spring Boot Starter使用测试 - 2

    目录SpringBootStarter是什么?以前传统的做法使用SpringBootStarter之后starter的理念:starter的实现: 创建SpringBootStarter步骤在idea新建一个starter项目、直接执行下一步即可生成项目。 在xml中加入如下配置文件:创建proterties类来保存配置信息创建业务类:创建AutoConfiguration测试如下:SpringBootStarter是什么? SpringBootStarter是在SpringBoot组件中被提出来的一种概念、简化了很多烦琐的配置、通过引入各种SpringBootStarter包可以快速搭建出一

  5. Spring Boot集成ElasticSearach - 2

    文章目录前言一、Elasticsearch版本介绍二、客户端种类三、客户端与版本兼容性四、引入Elasticsearch依赖包五、客户端配置六、Elasticsearch使用前言ElasticSearch是Elastic公司出品的一款功能强大的搜索引擎,被广泛的应用于各大IT公司,它的代码位于https://github.com/elastic/elasticsearch,目前是一个开源项目。ElasticSearch公司的另外两个开源产品Logstash、Kibana与ElasticSearch构成了著名的ELK技术栈。。他们三个共同形成了一个强大的生态圈。简单地说,Logstash负责数据

  6. Spring Security 6.0系列【32】授权服务器篇之默认过滤器 - 2

    有道无术,术尚可求,有术无道,止于术。本系列SpringBoot版本3.0.4本系列SpringSecurity版本6.0.2本系列SpringAuthorizationServer版本1.0.2源码地址:https://gitee.com/pearl-organization/study-spring-security-demo文章目录前言1.OAuth2AuthorizationServerMetadataEndpointFilter2.OAuth2AuthorizationEndpointFilter3.OidcProviderConfigurationEndpointFilter4.N

  7. IDEA 2022 创建 Spring Boot 项目详解 - 2

    如何用IDEA2022创建并初始化一个SpringBoot项目?目录如何用IDEA2022创建并初始化一个SpringBoot项目?0. 环境说明1.  创建SpringBoot项目 2.编写初始化代码0. 环境说明IDEA2022.3.1JDK1.8SpringBoot1.  创建SpringBoot项目        打开IDEA,选择NewProject创建项目。        填写项目名称、项目构建方式、jdk版本,按需要修改项目文件路径等信息。        选择springboot版本以及需要的包,此处只选择了springweb。        此处需特别注意,若你使用的是jdk1

  8. ruby-on-rails - 您已经激活了 spring 1.3.6,但是您的 Gemfile 需要 spring 1.3.3。 ( gem ::加载错误) - 2

    我今天遇到了同样的问题,有一个建议:在您的命令前添加bundleexec可能会解决此问题。前置bundleexec没有帮助(我已经这样做了)。springstop和springrestart没有帮助。我需要做的:bundleupdatespring这对我有用。在之前的gemlock文件中使用spring版本是否有更好的解决方案? 最佳答案 我删除gemfile.lock并运行bundle通常会清除一切。否则只需从Gemfile中删除gem"spring"并运行bundle 关于ruby-

  9. Spring Boot中的微信支付(小程序) - 2

    前言微信支付是企业级项目中经常使用到的功能,作为后端开发人员,完整地掌握该技术是十分有必要的。一、申请流程和步骤图1-1注册微信支付账号获取微信小程序APPID获取微信商家的商户ID获取微信商家的API私钥配置微信支付回调地址绑定微信小程序和微信支付的关系搭建SpringBoot工程编写后台支付接口发布部署接口服务项目使用微信小程序或者UniAPP调用微信支付功能支付接口的封装配置jwt或者openid的token派发原生微信小程序完成支付对接二、注册商家2.1商户平台商家或者企业想要通过微信支付来进行商品的销售,必须先通过微信平台(pay.weixin.qq.com)去将商家进行注册。注册成

  10. Spring Cloud Gateway 服务网关的部署与使用详细介绍 - 2

    为什么需要服务网关传统的单体架构中只需要开放一个服务给客户端调用,但是微服务架构中是将一个系统拆分成多个微服务,如果没有网关,客户端只能在本地记录每个微服务的调用地址,当需要调用的微服务数量很多时,它需要了解每个服务的接口,这个工作量很大。有了网关之后,网关作为系统的唯一流量入口,封装内部系统的架构,所有请求都先经过网关,由网关将请求路由到合适的微服务。使用网关的好处1)简化客户端的工作。网关将微服务封装起来后,客户端只需同网关交互,而不必调用各个不同服务;(2)降低函数间的耦合度。一旦服务接口修改,只需修改网关的路由策略,不必修改每个调用该函数的客户端,从而减少了程序间的耦合性(3)解放开发

随机推荐