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);

	// 检查容器中是否存在指定名称的 Bean
    boolean 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情况)
    @Nullable
    Class<?> getType(String name) throws NoSuchBeanDefinitionException;

	// 返回Bean的Class类型
	// allowFactoryBeanInit=true,初始化FactoryBean返回实际类型
    @Nullable
    Class<?> 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
	@Nullable
	BeanFactory getParentBeanFactory();
	// 判断本地 Bean 工厂是否包含指定名称的 Bean,忽略父级上下文中定义的 Bean
	boolean 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 {
	// 尝试解析指定代码的消息,如果找不到则返回默认消息
	@Nullable
	String 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
	@Nullable
	String getId();

	// 返回该上下文所属的已部署应用程序的名称,默认为空字符串
	String getApplicationName();
	
	// 返回此上下文的友好名称(显示名称),不会为null
	String getDisplayName();

	// 返回此上下文第一次加载时的时间戳(以毫秒为单位)
	long getStartupDate();

	// 父上下文,如果没有则返回null
	@Nullable
	ApplicationContext getParent();

	// 这个方法的作用是让开发者能够访问底层的 BeanFactory,从而手动管理和操作 Bean 的生命周期和依赖注入
	AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}

9、Lifecycle(Bean生命周期管理接口)

  Lifecycle是一个通用的生命周期接口,定义了组件的启动停止运行状态检查方法,通常用于控制具有生命周期管理能力的组件(如线程、定时任务、消息监听器等)。

public interface Lifecycle {

	// 启动组件,对于容器,它会将启动信号传播到容器内所有相关的子组件
	void start();

	// 停止组件,通常是同步操作,确保组件在方法返回时完全停止
	void stop();

	// 检查组件是否正在运行,只有当所有相关的子组件都运行时,才返回 true
	boolean 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";

	// 设置此应用程序上下文的唯一 ID
	void setId(String id);

	// 设置此应用程序上下文的父上下文
	void setParent(@Nullable ApplicationContext parent);

	// 设置此应用程序上下文的Environment
	void setEnvironment(ConfigurableEnvironment environment);

	// 返回此应用程序上下文的Environment
	@Override
	ConfigurableEnvironment getEnvironment();

	// 添加一个工厂处理器BeanFactoryPostProcessor,该处理器将在刷新时应用于内部 bean 工厂
	void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor);

	// 添加一个新的 ApplicationListener,该监听器将在上下文事件(如刷新或关闭)时被通知
	void addApplicationListener(ApplicationListener<?> listener);

	// 加载或刷新配置的持久化表示,例如基于 Java 配置、XML 文件、属性文件等
	void refresh() throws BeansException, IllegalStateException;

	// 向 JVM 注册一个关闭钩子,在 JVM 关闭时关闭此上下文
	void registerShutdownHook();
	
	// 关闭此应用程序上下文,释放所有资源并销毁所有缓存的单例 bean
	@Override
	void close();

	// 确定此应用程序上下文是否处于活动状态
	boolean isActive();

	// 返回此应用程序上下文的内部 BeanFactory
	ConfigurableListableBeanFactory 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 应用程序相关的上下文信息
	@Nullable
	ServletContext 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 应用程序上下文的 ServletContext
	void setServletContext(@Nullable ServletContext servletContext);
	// 设置此 Web 应用程序上下文的 ServletConfig
	void setServletConfig(@Nullable ServletConfig servletConfig);
	// 返回此 Web 应用程序上下文的 ServletConfig(如果有)
	@Nullable
	ServletConfig getServletConfig();


	// 设置此 Web 应用程序上下文的命名空间
	void setNamespace(@Nullable String namespace);
	// 返回此 Web 应用程序上下文的命名空间(如果有)
	@Nullable
	String getNamespace();

	
	// 以 init-param 样式设置此 Web 应用程序上下文的配置位置
	void setConfigLocation(String configLocation);
	// 设置此 Web 应用程序上下文的配置位置
	void setConfigLocations(String... configLocations);
	// 返回此 Web 应用程序上下文的配置位置
	@Nullable
	String[] getConfigLocations();
}

13、WebServerApplicationContext(web服务应用上下文)

  WebServerApplicationContext专门用于管理嵌入式Web服务器(如Tomcat、Jetty 或 Undertow)的生命周期。它提供了与Web服务器交互的抽象,支持启动、停止和运行时管理Web服务器的状态

public interface WebServerApplicationContext extends ApplicationContext {

	// 返回由上下文创建的内嵌的 Web 服务器实例,如果服务器尚未创建,则返回null
	WebServer getWebServer();
	
	// 返回Web服务器应用程序上下文的命名空间,如果未设置命名空间,则返回null
	String getServerNamespace();

	// 判断指定的上下文是否为WebServerApplicationContext,且具有匹配的服务器命名空间
	static boolean hasServerNamespace(ApplicationContext context, String serverNamespace) {
		return (context instanceof WebServerApplicationContext) 
上一篇:“云计算+中职”:VR虚拟仿真实训室的发展前景-四、结语


下一篇:react什么时候用箭头函数,什么时候不需要