SpringBoot源码解析(七):应用上下文结构体系
SpringBoot源码系列文章
SpringBoot源码解析(一):SpringApplication构造方法
SpringBoot源码解析(二):引导上下文DefaultBootstrapContext
SpringBoot源码解析(三):启动开始阶段
SpringBoot源码解析(四):解析应用参数args
SpringBoot源码解析(五):准备应用环境
SpringBoot源码解析(六):打印Banner
SpringBoot源码解析(七):应用上下文结构体系
目录
- 前言
- 一、AnnotationConfigServletWebServerApplicationContext类图
- 二、AnnotationConfigServletWebServerApplicationContext组件功能解析
- 1、BeanFactory(Bean管理核心接口)
- 2、HierarchicalBeanFactory(支持父子容器)
- 3、ListableBeanFactory(批量获取Bean)
- 4、MessageSource(国际化消息支持)
- 5、EnvironmentCapable(环境变量访问能力)
- 6、ResourcePatternResolver(资源路径解析器)
- 7、ApplicationEventPublisher(发布事件)
- 8、ApplicationContext(应用上下文核心接口)
- 9、Lifecycle(Bean生命周期管理接口)
- 10、ConfigurableApplicationContext(可配置应用上下文)
- 11、WebApplicationContext(web应用上下文)
- 12、ConfigurableWebApplicationContext(可配置web应用上下文)
- 13、WebServerApplicationContext(web服务应用上下文)
- 14、ConfigurableWebServerApplicationContext(可配置web服务应用上下文)
- 15、AbstractApplicationContext(抽象应用上下文)
- 16、BeanDefinitionRegistry(Bean定义注册接口)
- 17、GenericApplicationContext(通用应用上下文)
- 18、GenericWebApplicationContext(web通用应用上下文)
- 19、ServletWebServerApplicationContext(web服务通用上下文)
- 20、AnnotationConfigRegistry(注解配置注册器)
- 21、AnnotationConfigServletWebServerApplicationContext(注解驱动web服务应用上下文)
- 总结
前言
在解析SpringBoot源码之前,需要对其使用的应用上下文(ApplicationContext)相关组件有清晰的了解。SpringBoot的核心在于基于Spring的扩展,其自动配置机制、嵌入式Web容器等特性都依赖于一套规范的上下文组件。因此,提前理清这些核心组件的功能和职责,可以显著提高源码阅读的效率,避免频繁地在代码中跳转而迷失方向。
SpringBoot在调用SpringApplication.run()方法启动时,根据应用类型(如 Servlet 类型)通过createApplicationContext()方法推断并创建AnnotationConfigServletWebServerApplicationContext,用于初始化和管理 Web 应用的上下文环境。

一、AnnotationConfigServletWebServerApplicationContext类图
类图如下(摆这个图用我好长时间🙇♂️),每个类的作用将在下面进行简要分析。

二、AnnotationConfigServletWebServerApplicationContext组件功能解析
1、BeanFactory(Bean管理核心接口)
BeanFactory是Spring框架中最基础的IOC(Inversion of Control,控制反转)容器接口,它负责创建、管理和配置应用中的Bean(对象),并处理Bean的依赖注入与生命周期管理。BeanFactory支持延迟加载(懒加载),即在首次请求时才实例化Bean,适用于轻量级应用或资源受限的环境。
public interface BeanFactory {// bean名称前加&,返回的FactoryBean工厂实例,否则返回实际创建类型实例String FACTORY_BEAN_PREFIX = "&";// 根据指定的名称获取Bean实例// 返回的实例可能是单例模式下的共享实例,也可能是每次请求都会创建的新实例,具体取决于 Bean 的配置// 如果容器中不存在该名称的 Bean,则会抛出异常Object getBean(String name) throws BeansException;// 根据指定的名称和类型获取Bean实例// 如果名称对应的 Bean 类型与指定的类型不匹配,则会抛出异常<T> T getBean(String name, Class<T> requiredType) throws BeansException;// 根据指定的名称和参数获取Bean实例Object getBean(String name, Object... args) throws BeansException;// 根据指定的类型获取唯一匹配的Bean实例// 如果容器中不存在该类型的 Bean,或者存在多个该类型的 Bean,则会抛出异常 <T> T getBean(Class<T> requiredType) throws BeansException;// 根据指定的类型和参数获取Bean实例<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;// 返回一个可以提供指定类型Bean的ObjectProvider对象// ObjectProvider不会立即实例化Bean,只有在调用其方法时才会加载或创建Bean<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);// 通过ResolvableType,可以获取复杂类型或泛型Bean// 可以定义复杂的泛型结构,如 List<MyBean>、Map<String, MyBean> 等<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);// 检查容器中是否存在指定名称的 Beanboolean containsBean(String name);// 检查指定名称的Bean是否为单例(一个类只能有一个实例)boolean isSingleton(String name) throws NoSuchBeanDefinitionException;// 检查指定名称的Bean是否为原型(每次获取返回一个新实例)boolean isPrototype(String name) throws NoSuchBeanDefinitionException;// 检查指定名称的Bean是否匹配某个ResolvableType// 例如,检查一个Bean是否是List<String>类型boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;// 检查指定名称的Bean是否匹配某个Class类型// 这是基础的类型匹配检查,不支持泛型,但速度更快boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;// 返回Bean的Class类型(不考虑FactoryBean情况)@NullableClass<?> getType(String name) throws NoSuchBeanDefinitionException;// 返回Bean的Class类型// allowFactoryBeanInit=true,初始化FactoryBean返回实际类型@NullableClass<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;// 获取Bean的所有别名String[] getAliases(String name);
}
2、HierarchicalBeanFactory(支持父子容器)
HierarchicalBeanFactory是Spring框架中定义的一个接口,它扩展了BeanFactory,用于支持Bean工厂的层次化结构管理。它的设计目的是允许一个Bean工厂拥有父级Bean工厂,并能够在当前Bean工厂和父级工厂之间协调Bean的管理和查找。
public interface HierarchicalBeanFactory extends BeanFactory {// 返回父级Bean工厂,如果没有父级,则返回null@NullableBeanFactory getParentBeanFactory();// 判断本地 Bean 工厂是否包含指定名称的 Bean,忽略父级上下文中定义的 Beanboolean containsLocalBean(String name);
}
3、ListableBeanFactory(批量获取Bean)
ListableBeanFactory是Spring框架中的一个接口,它扩展了BeanFactory,提供了按照类型、名称等多种方式列出Bean的功能。它是Spring应用上下文中一个核心接口,用于管理和访问Bean。
// "只考虑当前工厂":检查范围限定为当前工厂的直接定义部分
// "不考虑层次结构":不会递归查询父工厂或祖先工厂中的定义
public interface ListableBeanFactory extends BeanFactory { // 检查此 Bean 工厂是否包含具有给定名称的 Bean 定义boolean containsBeanDefinition(String beanName);// 返回工厂中定义的 Bean 数量int getBeanDefinitionCount();// 返回此工厂中定义的所有 Bean 的名称String[] getBeanDefinitionNames();// 返回一个可以提供指定类型Bean的ObjectProvider对象,可选择是否延迟初始化<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType, boolean allowEagerInit);// 返回一个可以提供复杂指定类型Bean的ObjectProvider对象,可选择是否延迟初始化<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType, boolean allowEagerInit);// 返回与给定类型(包括给定类型子类)匹配的 Bean 名称String[] getBeanNamesForType(ResolvableType type);// 返回与给定复杂类型(包括给定子类)匹配的 Bean 名称// 并允许对非单例 Bean 和延迟加载 Bean 进行控制String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit);// 返回与给定类型(包括子类)匹配的 Bean 名称String[] getBeanNamesForType(@Nullable Class<?> type);// 返回与给定类型(包括子类)匹配的 Bean 名称// 并允许对非单例 Bean 和延迟加载 Bean 进行控制String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);// 返回一个 Map,包含匹配的 Bean 名称和对应的 Bean 实例<T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;// 返回一个 Map,包含匹配的 Bean 名称和对应的 Bean 实例// 并允许对非单例 Bean 和延迟加载 Bean 进行控制<T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)throws BeansException;// 查找带有指定注解的所有 Bean 名称String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);// 一个 Map,包含匹配的 Bean 名称和对应带指定注解的Bean实例Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;// 用于查找指定 Bean 上的特定类型注解,并返回该注解的实例@Nullable<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)throws NoSuchBeanDefinitionException;// 用于查找指定 Bean 上的特定注解,并提供一个参数来控制是否允许初始化 FactoryBean@Nullable<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType, boolean allowFactoryBeanInit)throws NoSuchBeanDefinitionException;
}
4、MessageSource(国际化消息支持)
MessageSource是SpringFramework中用于国际化的接口,主要用来处理应用程序中的多语言消息。它允许你根据用户的语言环境(Locale)来动态加载和显示相应的消息。这对于支持多语言的应用程序非常重要。
// 消息解析的策略接口,支持消息的参数化和国际化
public interface MessageSource {// 尝试解析指定代码的消息,如果找不到则返回默认消息@NullableString getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);// 尝试解析消息。如果未找到消息,视为错误并抛出异常String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException;// 根据传入的 MessageSourceResolvable 参数解析消息,若未找到对应消息,抛出异常String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
}
5、EnvironmentCapable(环境变量访问能力)
EnvironmentCapable是SpringFramework中的一个接口,它定义了获取Environment的能力。Environment是Spring的核心抽象之一,用于表示当前应用程序的环境信息,比如操作系统属性、配置属性、环境变量等。
public interface EnvironmentCapable {// 返回一个 Environment 对象,Environment 提供了多个方法来获取配置信息Environment getEnvironment();
}
6、ResourcePatternResolver(资源路径解析器)
ResourcePatternResolver是Spring框架中的一个接口,用于将路径模式(如通配符 * 和 **)解析为资源(Resource)对象。简单来说,它提供了一种机制,可以通过路径模式加载符合条件的资源文件,比如从类路径、文件系统或 JAR 文件中加载多个资源。
public interface ResourcePatternResolver extends ResourceLoader {// 用于从类路径中匹配所有资源的伪 URL 前缀:"classpath*:"String CLASSPATH_ALL_URL_PREFIX = "classpath*:";// 解析给定路径的资源,解析为Resource对象Resource[] getResources(String locationPattern) throws IOException;
}
7、ApplicationEventPublisher(发布事件)
ApplicationEventPublisher是SpringFramework中的一个接口,用于将事件发布给监听器。它是Spring事件驱动编程模型的核心组件之一,能够实现组件之间的解耦通信。之前文章Spring发布-订阅模式:解耦与异步通信的高效实现对于此类有详细介绍
// 一个封装事件发布功能的接口
@FunctionalInterface
public interface ApplicationEventPublisher {// 默认方法,最终还是调用publishEvent(Object event)方法default void publishEvent(ApplicationEvent event) {publishEvent((Object) event);}// 发布事件void publishEvent(Object event);
}
8、ApplicationContext(应用上下文核心接口)
ApplicationContext是Spring框架中的一个中央接口,它提供了对Bean工厂、事件发布、消息解析等核心功能的统一访问。
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,MessageSource, ApplicationEventPublisher, ResourcePatternResolver {// 返回此应用程序上下文的唯一标识符,没有返回null@NullableString getId();// 返回该上下文所属的已部署应用程序的名称,默认为空字符串String getApplicationName();// 返回此上下文的友好名称(显示名称),不会为nullString getDisplayName();// 返回此上下文第一次加载时的时间戳(以毫秒为单位)long getStartupDate();// 父上下文,如果没有则返回null@NullableApplicationContext getParent();// 这个方法的作用是让开发者能够访问底层的 BeanFactory,从而手动管理和操作 Bean 的生命周期和依赖注入AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}
9、Lifecycle(Bean生命周期管理接口)
Lifecycle是一个通用的生命周期接口,定义了组件的启动、停止和运行状态检查方法,通常用于控制具有生命周期管理能力的组件(如线程、定时任务、消息监听器等)。
public interface Lifecycle {// 启动组件,对于容器,它会将启动信号传播到容器内所有相关的子组件void start();// 停止组件,通常是同步操作,确保组件在方法返回时完全停止void stop();// 检查组件是否正在运行,只有当所有相关的子组件都运行时,才返回 trueboolean isRunning();
}
10、ConfigurableApplicationContext(可配置应用上下文)
ConfigurableApplicationContext是Spring应用上下文接口的扩展,定义了可配置的应用上下文,主要用于管理、配置和控制Spring 应用上下文的生命周期。它在 ApplicationContext 的基础上增加了许多高级功能,例如上下文刷新、关闭、父上下文设置等。
public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {// 配置路径中多个配置路径之间的分隔符字符// 可以是逗号 (`,`)、分号 (`;`)、空格 (` `)、制表符 (`\t`) 或换行符 (`\n`)String CONFIG_LOCATION_DELIMITERS = ",; \t\n";// BeanFactory 中 ConversionService bean 的名称String CONVERSION_SERVICE_BEAN_NAME = "conversionService";// BeanFactory 中 LoadTimeWeaver bean 的名称String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver";// BeanFactory 中 Environment bean 的名称String ENVIRONMENT_BEAN_NAME = "environment";// BeanFactory 中系统属性的 Bean 名称String SYSTEM_PROPERTIES_BEAN_NAME = "systemProperties";// BeanFactory 中系统环境变量的 Bean 名称String SYSTEM_ENVIRONMENT_BEAN_NAME = "systemEnvironment";// BeanFactory 中 ApplicationStartup bean 的名称// 收集和记录应用程序启动过程中的性能指标,省略不细讲String APPLICATION_STARTUP_BEAN_NAME = "applicationStartup";// JVM 中关闭钩子线程的默认名称String SHUTDOWN_HOOK_THREAD_NAME = "SpringContextShutdownHook";// 设置此应用程序上下文的唯一 IDvoid setId(String id);// 设置此应用程序上下文的父上下文void setParent(@Nullable ApplicationContext parent);// 设置此应用程序上下文的Environmentvoid setEnvironment(ConfigurableEnvironment environment);// 返回此应用程序上下文的Environment@OverrideConfigurableEnvironment getEnvironment();// 添加一个工厂处理器BeanFactoryPostProcessor,该处理器将在刷新时应用于内部 bean 工厂void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor);// 添加一个新的 ApplicationListener,该监听器将在上下文事件(如刷新或关闭)时被通知void addApplicationListener(ApplicationListener<?> listener);// 加载或刷新配置的持久化表示,例如基于 Java 配置、XML 文件、属性文件等void refresh() throws BeansException, IllegalStateException;// 向 JVM 注册一个关闭钩子,在 JVM 关闭时关闭此上下文void registerShutdownHook();// 关闭此应用程序上下文,释放所有资源并销毁所有缓存的单例 bean@Overridevoid close();// 确定此应用程序上下文是否处于活动状态boolean isActive();// 返回此应用程序上下文的内部 BeanFactoryConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
}
11、WebApplicationContext(web应用上下文)
WebApplicationContext是Spring框架中专门为Web应用设计的上下文接口。它扩展了ApplicationContext,增加了与Servlet API的集成功能,例如访问 ServletContext,支持Web特定的作用域(如request和session),并且通过分层结构实现了灵活的上下文管理。
public interface WebApplicationContext extends ApplicationContext {// 常量,表示根 WebApplicationContext 在启动过程中绑定到的属性名称// 用于在 Web 应用程序中查找根上下文,例如通过 WebApplicationContextUtils 工具类String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";// 分别对应请求范围(request)、会话范围(session)、全局应用范围(application)String SCOPE_REQUEST = "request";String SCOPE_SESSION = "session";String SCOPE_APPLICATION = "application";// 定义了 ServletContext 在 Spring 容器中的 Bean 名称String SERVLET_CONTEXT_BEAN_NAME = "servletContext";// 定义了 ServletContext 初始化参数(init-params)在 Spring 容器中的 Bean 名称。// 如果参数在 ServletConfig 和 ServletContext 中同名,则 ServletConfig 参数优先。String CONTEXT_PARAMETERS_BEAN_NAME = "contextParameters";// 定义了 ServletContext 属性(attributes)在 Spring 容器中的 Bean 名称String CONTEXT_ATTRIBUTES_BEAN_NAME = "contextAttributes";// 返回当前应用程序的 ServletContext 对象。// 可用于直接访问与 Web 应用程序相关的上下文信息@NullableServletContext getServletContext();
}
12、ConfigurableWebApplicationContext(可配置web应用上下文)
ConfigurableWebApplicationContext是一个用于管理和配置Web应用上下文的接口,支持与Servlet环境集成、动态加载配置文件以及命名空间管理。
// 此接口主要用于管理基于 Web 的应用程序上下文,并提供特定于 Web 环境的配置方法
public interface ConfigurableWebApplicationContext extends WebApplicationContext, ConfigurableApplicationContext {// 用于引用上下文路径和/或 Servlet 名称的 ApplicationContext id 前缀String APPLICATION_CONTEXT_ID_PREFIX = WebApplicationContext.class.getName() + ":";// 在工厂中表示 ServletConfig 环境 Bean 的名称String SERVLET_CONFIG_BEAN_NAME = "servletConfig";// 设置此 Web 应用程序上下文的 ServletContextvoid setServletContext(@Nullable ServletContext servletContext);// 设置此 Web 应用程序上下文的 ServletConfigvoid setServletConfig(@Nullable ServletConfig servletConfig);// 返回此 Web 应用程序上下文的 ServletConfig(如果有)@NullableServletConfig getServletConfig();// 设置此 Web 应用程序上下文的命名空间void setNamespace(@Nullable String namespace);// 返回此 Web 应用程序上下文的命名空间(如果有)@NullableString getNamespace();// 以 init-param 样式设置此 Web 应用程序上下文的配置位置void setConfigLocation(String configLocation);// 设置此 Web 应用程序上下文的配置位置void setConfigLocations(String... configLocations);// 返回此 Web 应用程序上下文的配置位置@NullableString[] getConfigLocations();
}
13、WebServerApplicationContext(web服务应用上下文)
WebServerApplicationContext专门用于管理嵌入式Web服务器(如Tomcat、Jetty 或 Undertow)的生命周期。它提供了与Web服务器交互的抽象,支持启动、停止和运行时管理Web服务器的状态。
public interface WebServerApplicationContext extends ApplicationContext {// 返回由上下文创建的内嵌的 Web 服务器实例,如果服务器尚未创建,则返回nullWebServer getWebServer();// 返回Web服务器应用程序上下文的命名空间,如果未设置命名空间,则返回nullString getServerNamespace();// 判断指定的上下文是否为WebServerApplicationContext,且具有匹配的服务器命名空间static boolean hasServerNamespace(ApplicationContext context, String serverNamespace) {return (context instanceof WebServerApplicationContext) && ObjectUtils.nullSafeEquals(((WebServerApplicationContext) context).getServerNamespace(), serverNamespace);}// 如果指定的上下文是WebServerApplicationContext,则返回其服务器命名空间static String getServerNamespace(ApplicationContext context) {return (context instanceof WebServerApplicationContext)? ((WebServerApplicationContext) context).getServerNamespace() : null;}}// 简单的接口,表示一个完全配置的 Web 服务器(例如 Tomcat、Jetty 或 Netty)
public interface WebServer {// 启动 Web 服务器void start() throws WebServerException;// 停止 Web 服务器。void stop() throws WebServerException;// 返回监听的端口号,如果未分配端口则返回 -1int getPort();// 允许在不影响现有请求的情况下优雅地关闭服务器// 默认实现是直接返回立即关闭的结果,可以被覆盖实现实际的关闭逻辑default void shutDownGracefully(GracefulShutdownCallback callback) {// 默认行为:直接调用回调函数,立即完成关闭(不实际执行关闭逻辑)callback.shutdownComplete(GracefulShutdownResult.IMMEDIATE);}
}
14、ConfigurableWebServerApplicationContext(可配置web服务应用上下文)
ConfigurableWebServerApplicationContext是一个用于配置和管理嵌入式Web服务器的Spring应用上下文接口,支持动态配置、服务器命名空间设置以及上下文生命周期管理。
// 通过此接口,开发者可以在 Web 服务器应用上下文中进行更灵活的配置和管理
public interface ConfigurableWebServerApplicationContextextends ConfigurableApplicationContext, WebServerApplicationContext {// 设置上下文的服务器命名空间。// 服务器命名空间通常用于区分不同的 Web 服务器实例或模块,尤其在复杂的微服务架构中非常有用。void setServerNamespace(String serverNamespace);
}
15、AbstractApplicationContext(抽象应用上下文)
AbstractApplicationContext是Spring应用上下文的抽象实现类,负责提供通用的上下文生命周期管理、事件发布、资源加载以及BeanFactory的初始化等核心功能。
所有具体的应用上下文(如 ClassPathXmlApplicationContext 和 AnnotationConfigApplicationContext)都继承自它。
public abstract class AbstractApplicationContext extends DefaultResourceLoaderimplements ConfigurableApplicationContext {... // 内容很多,这里只介绍下核心内容/*** 核心属性*/// bean工厂后置处理器// 在容器刷新时,允许在 Bean 定义加载完成但 Bean 实例化之前,修改 Bean 定义private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();// 生命周期处理器,用于管理应用上下文中所有实现了 Lifecycle 接口的组件的启动和停止// 容器刷新时(onRefresh() 方法),启动所有实现了 Lifecycle 或 SmartLifecycle 接口的 Bean// 容器关闭时(onClose() 方法),停止所有实现了 Lifecycle 或 SmartLifecycle 接口的 Bean@Nullableprivate LifecycleProcessor lifecycleProcessor;// 事件广播器,负责将发布的事件分发给所有注册的监听器@Nullableprivate ApplicationEventMulticaster applicationEventMulticaster;// 用于存储在上下文刷新之前显式注册的 ApplicationListener// 这些监听器在容器初始化时注册,并在事件发布时被调用private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();/*** 核心方法*/// 核心方法,用于刷新上下文的配置和状态@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 1、刷新前预处理prepareRefresh();// 2、获取最新的bean工厂ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 3、注册bean工厂的类加载器和部分后置处理器prepareBeanFactory(beanFactory);try {// 4、bean工厂的后置处理器(子类实现)postProcessBeanFactory(beanFactory);// 5、执行bean工厂的后置处理器invokeBeanFactoryPostProcessors(beanFactory);// 6、注册所有的后置处理器registerBeanPostProcessors(beanFactory);// 7、初始化国际化组件initMessageSource();// 8、初始化事件多播器(用来广播事件)initApplicationEventMulticaster();// 9、子类实现,扩展其他beanonRefresh();// 10、注册监听器registerListeners();// 11、实例化,初始化所有的非懒加载的单例beanfinishBeanFactoryInitialization(beanFactory);// 12、最后刷新,发布相应事件finishRefresh();}catch (BeansException ex) {...}}}// 发布事件到所有监听器。如果事件多播器尚未初始化,将事件存储以供后续处理// ApplicationEventPublisher接口的实现@Overridepublic void publishEvent(ApplicationEvent event) {...}// 注册 JVM 关闭钩子,确保上下文在 JVM 关闭时也能被正确关闭@Overridepublic void registerShutdownHook() {...}// 关闭上下文,销毁所有单例 Bean,并发布关闭事件@Overridepublic void close() {...}}
16、BeanDefinitionRegistry(Bean定义注册接口)
BeanDefinitionRegistry是Spring容器中用于管理Bean定义的核心接口,支持动态注册、移除、查询和别名管理,常用于扩展和动态操作容器内的 Bean 定义。
// 此接口是 Bean 定义注册的核心,用于动态管理 Bean 定义(注册、移除、查询等)
public interface BeanDefinitionRegistry extends AliasRegistry {// 向注册表中注册一个新的 BeanDefinitionvoid registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException;// 移除给定名称的 BeanDefinitionvoid removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;// 返回给定名称的 BeanDefinitionBeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;// 检查此注册表是否包含具有给定名称的 BeanDefinition。boolean containsBeanDefinition(String beanName);// 返回此注册表中定义的所有 Bean 的名称String[] getBeanDefinitionNames();// 返回注册表中定义的 Bean 的数量。int getBeanDefinitionCount();// 确定给定的 Bean 名称是否已经在此注册表中使用(即是否有本地 Bean 或别名注册了此名称)boolean isBeanNameInUse(String beanName);
}/*** 管理别名的通用接口(提供了注册、删除、查询别名的方法)** 别名是一种机制,用于为已有的名称提供额外的标识,* 通常用于配置中增加灵活性,例如为同一个 Bean 定义多个名称*/
public interface AliasRegistry {// 为给定的名称注册一个别名void registerAlias(String name, String alias);// 从注册表中删除指定的别名void removeAlias(String alias);// 确定给定的名称是否被定义为别名(而不是实际注册的组件名称)boolean isAlias(String name);// 返回给定名称的所有别名(如果定义了别名)String[] getAliases(String name);
}
17、GenericApplicationContext(通用应用上下文)
GenericApplicationContext是一个通用的Spring应用上下文容器,支持以编程方式注册Bean和灵活配置应用上下文
DefaultListableBeanFactory内部组件较为复杂,下篇文章将单独对其内部组件进行详细解析。
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {... // 内容很多,这里只介绍下核心内容// 用于注册、管理和创建 Bean 定义,支持依赖注入和动态 Bean 管理private final DefaultListableBeanFactory beanFactory;// 用于统一加载文件、类路径、URL 等各种类型的资源@Nullableprivate ResourceLoader resourceLoader;// 根据给定路径加载单个资源,支持自定义协议解析和默认资源加载器@Overridepublic Resource getResource(String location) {...}// 根据路径模式加载多个资源,优先使用资源加载器的路径解析能力@Overridepublic Resource[] getResources(String locationPattern) throws IOException {...}@Override// 向底层 Bean 工厂注册一个新的 Bean 定义public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException {this.beanFactory.registerBeanDefinition(beanName, beanDefinition);}@Override// 从底层 Bean 工厂中移除指定名称的 Bean 定义public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {this.beanFactory.removeBeanDefinition(beanName);}@Override// 获取指定名称的 Bean 定义public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {return this.beanFactory.getBeanDefinition(beanName);}// registerBean 方法封装了 Bean 注册的逻辑// 允许通过 Class 类型、可选的实例供应器和自定义器动态注册 Bean// 极大简化了 Bean 定义和注册的过程public <T> void registerBean(@Nullable String beanName, Class<T> beanClass,@Nullable Supplier<T> supplier, BeanDefinitionCustomizer... customizers) {...}}
18、GenericWebApplicationContext(web通用应用上下文)
GenericWebApplicationContext是一个通用的Spring Web应用上下文,结合动态Bean注册功能与Web特定特性(如ServletContext),用于轻量化配置和管理 Web 应用环境
public class GenericWebApplicationContext extends GenericApplicationContextimplements ConfigurableWebApplicationContext, ThemeSource {// ServletContext 是 Web 应用的全局上下文// 用于共享数据、加载资源、解析路径和访问应用及容器的配置信息@Nullableprivate ServletContext servletContext;...
}
19、ServletWebServerApplicationContext(web服务通用上下文)
ServletWebServerApplicationContext是SpringBoot用于启动和管理内嵌Servlet Web服务器(如 Tomcat)的应用上下文,实现Web服务器与Spring容器的无缝集成。
public class ServletWebServerApplicationContext extends GenericWebApplicationContextimplements ConfigurableWebServerApplicationContext {// 表示一个Web服务器(例如 Tomcat、Jetty 或 Netty)private volatile WebServer webServer;// ServletConfig 是 Servlet 规范中的接口// 用于向 Servlet 提供初始化参数和上下文信息private ServletConfig servletConfig;// 创建和初始化内嵌 Web 服务器private void createWebServer() {...}
}
20、AnnotationConfigRegistry(注解配置注册器)
AnnotationConfigRegistry是一个接口,提供通过注册注解配置类或扫描包路径来管理Spring组件的功能。
// 主要功能是提供通过注解方式注册组件类或扫描包的能力
public interface AnnotationConfigRegistry {// 注册一个或多个组件类// 对register方法的调用是幂等的;多次添加相同的组件类不会产生额外的效果void register(Class<?>... componentClasses);// 扫描指定的基础包以查找组件类void scan(String... basePackages);
}
21、AnnotationConfigServletWebServerApplicationContext(注解驱动web服务应用上下文)
AnnotationConfigServletWebServerApplicationContext是一个基于注解配置的 Spring 应用上下文,继承自 ServletWebServerApplicationContext,并支持通过注解注册组件类和包扫描来配置 Web 应用。
// 一个专门用于基于注解配置的 Servlet Web 服务器应用上下文
public class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContextimplements AnnotationConfigRegistry {// 存储已注册的注解配置类的集合,这些类通常标注有@Configuration注解private final Set<Class<?>> annotatedClasses = new LinkedHashSet<>();// 存储要扫描的基础包路径数组,通过包路径扫描,可以发现并注册 Spring 组件private String[] basePackages;...
}
总结
- SpringBoot的上下文架构基于Spring的扩展,核心是以
ApplicationContext为中心的组件体系- 通过
BeanFactory提供Bean的注册、管理和依赖注入功能 - 通过
ApplicationContext为应用提供高级功能支持,包括国际化消息、访问环境变量、事件发布、资源访问等 - 通过
WebApplicationContext集成ServletContext,管理Web环境中的Bean和特定作用域(如request和session) - 通过
WebServerApplicationContext管理嵌入式Web服务器(如 Tomcat、Jetty)的启动、停止和生命周期
- 通过
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=5dxybut99es
相关文章:
SpringBoot源码解析(七):应用上下文结构体系
SpringBoot源码系列文章 SpringBoot源码解析(一):SpringApplication构造方法 SpringBoot源码解析(二):引导上下文DefaultBootstrapContext SpringBoot源码解析(三):启动开始阶段 SpringBoot源码解析(四):解析应用参数args Sp…...
SpringSecurity-前后端分离
在前后端分离的架构中,Spring Security 的配置与传统的单体应用有所不同。为了确保安全性和灵活性,我们需要对 Spring Security 进行适当的调整以适应这种架构。下面将详细介绍如何在前后端分离的应用程序中实现 Spring Security。 1. 理解前后端分离的…...
sparkRDD教程之基本命令
作者:nchu可乐百香果 指导者:nchu-YoungDragon 1.前期准备 (1)从迅雷网盘上面下载这个项目,并且把scala,maven和java环境配置好 网盘链接: 分享文件:SparkRDD.zip 链接…...
Linux:SystemV通信
目录 一、System V通信 二、共享内存 代码板块 总结 三、信号量 信号量理论 信号量接口 一、System V通信 System V IPC(inter-process communication),是一种进程间通信方式。其实现的方法有共享内存、消息队列、信号量这三种机制。 …...
C#上位机通过CAN总线发送bin文件
让gpt生成一段代码用来把bin文件通过can总线发出去 c#代码还是比较强大的,各种功能基本都是一两行代码就实现了,这里记录一下对这个代码的理解和解读 主要代码如下,传入bin文件的地址即可将其从指定的can通道发送出去: public …...
CV 图像处理基础笔记大全(超全版哦~)!!!
一、图像的数字化表示 像素 数字图像由众多像素组成,是图像的基本构成单位。在灰度图像中,一个像素用一个数值表示其亮度,通常 8 位存储,取值范围 0 - 255,0 为纯黑,255 为纯白。例如,一幅简单的…...
2-Kbengine+Unity3D多人在线游戏DEMO源码架构分析
2-Kbengine+Unity3D多人在线游戏DEMO源码架构分析 目录 一、服务器端 1、编写并生成我们的服务器端和客户端通用的游戏协议 2、 认识Entity实体 3、 官方DEMO-kbengine_demos_assets分析 二、 客户端...
Vue.js组件开发-如何实现表头搜索
在Vue.js组件开发中,实现表头搜索通常涉及在表格组件的表头添加输入框,并让用户能够输入搜索关键字来过滤表格数据。 以下是一个使用Element UI的el-table组件实现表头搜索的示例: 一、准备阶段 确保Element UI已安装: 确保…...
lerna使用指南
lerna版本 以下所有配置命令都是基于v8.1.9,lerna v5 v7版本差别较大,在使用时,注意自身的lerna版本。 lerna开启缓存及缓存配置 nx缓存是v5版本以后才有的,小于该版本的无法使用该功能。 初始化配置 缓存配置文件nx.json&am…...
spark,读取和写入同一张表问题
读取a表,写入a表 1.写入的是分区表,不报错 2.读取上来之后,创建为临时视图temp,然后先写入a表,再使用temp,就会报错 解决办法:可以先使用temp,再写入a表 3.写入的不是分区表&…...
iOS - TLS(线程本地存储)
从源码中,详细总结 TLS (Thread Local Storage) 的实现: 1. TLS 基本结构 // TLS 的基本结构 struct tls_data {pthread_key_t key; // 线程本地存储的键void (*destructor)(void *); // 清理函数 };// 自动释放池的 TLS class Autorelease…...
node.js项目依赖关系分析工具 Depazer 的使用
node.js项目依赖关系分析工具 Depazer 的使用 Depazer 是一个用于 分析和可视化 Node.js 项目依赖关系 的工具。它可以帮助开发者快速了解项目的依赖结构、模块关系,以及可能存在的问题,从而优化代码架构和依赖管理。 功能特点 依赖关系分析࿱…...
QT 如何禁止QComboBox鼠标滚轮
一般情况下,QComboBox会相应鼠标的滚轮事件,即当鼠标停靠在QComboBox上方时,滚动鼠标滚轮,QComboBox的选项会发生切换。但这或许并不是我们希望所出现的,尤其是当QComboBox嵌入在QScrollArea中时,用户只是想…...
理解CPU负载与使用率
目录 CPU使用率 CPU负载 CPU使用率 定义:就像看一个工人干活的时间占他上班时间的比例。比如工人上班8小时,实际干活6小时,干活时间占比就是68100%75%。对于CPU,单核的看它被占用的时间占总时间的比例,多核的就把每个…...
浅谈计算机网络01 | SDN数据平面
浅谈基本云架构 一、计算机网络数据平面的基础理论1.1 数据平面与控制平面的区分1.1.1 两者功能差异1.1.2 协同工作机制 1.2 数据平面在网络架构中的位置与角色1.2.1 与各网络层次的关系1.2.2 对网络整体性能的影响 二、数据平面的关键技术原理2.1 转发技术2.1.1 基于目的地转发…...
《Java开发手册》核心内容
文章目录 引言I 编程规约II 异常日志III 单元测试 :IV 安全规约 :V MySQL数据库:VI 工程结构 :VII 设计规约 :引言 手册的愿景是提升代码质量和开发效率,通过规范化的编码实践来减少错误和提高系统的稳定性。 I 编程规约 命名风格:规定了命名的一致性和规范性,避免使…...
采用海豚调度器+Doris开发数仓保姆级教程(满满是踩坑干货细节,持续更新)
目录 一、采用海豚调度器+Doris开发平替CDH Hdfs + Yarn + Hive + Oozie的理由。 1. 架构复杂性 2. 数据处理性能 3. 数据同步与更新 4. 资源利用率与成本 6. 生态系统与兼容性 7. 符合信创或国产化要求 二、ODS层接入数据 接入kafka实时数据 踩坑的问题细节 三、海…...
通过将模型权重的矩阵表示为低秩矩阵,可以减少需要调整的参数数量,通俗易懂的解释,不懂你爬网线打我
通过将模型权重矩阵表示为低秩矩阵,可以减少需要调整的参数数量,原因在于低秩矩阵的结构本身就比高秩矩阵更“紧凑”,即它们需要的独立参数更少。具体来说,低秩矩阵的结构可以通过减少模型的自由度(独立参数的数量&…...
Java并发编程——线程池(基础,使用,拒绝策略,命名,提交方式,状态)
我是一个计算机专业研0的学生卡蒙Camel🐫🐫🐫(刚保研) 记录每天学习过程(主要学习Java、python、人工智能),总结知识点(内容来自:自我总结网上借鉴࿰…...
DilateFormer: Multi-Scale Dilated Transformer for Visual Recognition 中的空洞自注意力机制
空洞自注意力机制 文章目录 摘要1. 模型解释1.1. 滑动窗口扩张注意力1.2. 多尺度扩张注意力 2. 代码3. 流程图3.1. MultiDilatelocalAttention3.2. DilateAttention3.3. MLP 摘要 本文针对DilateFormer中的空洞自注意力机制原理和代码进行详细介绍,最后通过流程图梳…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...
【JVM】Java虚拟机(二)——垃圾回收
目录 一、如何判断对象可以回收 (一)引用计数法 (二)可达性分析算法 二、垃圾回收算法 (一)标记清除 (二)标记整理 (三)复制 (四ÿ…...
三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...
