SpringBoot源码解析(十):应用上下文AnnotationConfigServletWebServerA
- 开源代码
- 2025-08-30 03:45:02

SpringBoot源码系列文章
SpringBoot源码解析(一):SpringApplication构造方法
SpringBoot源码解析(二):引导上下文DefaultBootstrapContext
SpringBoot源码解析(三):启动开始阶段
SpringBoot源码解析(四):解析应用参数args
SpringBoot源码解析(五):准备应用环境
SpringBoot源码解析(六):打印Banner
SpringBoot源码解析(七):应用上下文结构体系
SpringBoot源码解析(八):Bean工厂接口体系
SpringBoot源码解析(九):Bean定义接口体系
SpringBoot源码解析(十):应用上下文AnnotationConfigServletWebServerApplicationContext构造方法
目录 前言源码入口一、初始化注解Bean定义读取器1、BeanDefinitionRegistry(Bean定义注册接口)2、获取环境对象Environment3、注册注解配置处理器3.1、获取默认Bean工厂3.2、注册后置处理器(注册Bean定义) 二、初始化类路径Bean定义扫描器1、注册默认注解过滤器2、自定义包扫描 总结 前言
在前文中,我们了解了应用上下文、Bean工厂以及Bean定义的核心组件功能,接下来,我们将深入探讨应用上下文的构造方法。
SpringBoot版本2.7.18SpringApplication的run方法的执行逻辑如下,本文将详细介绍第6小节:创建应用程序上下文
// SpringApplication类方法 public ConfigurableApplicationContext run(String... args) { // 记录应用启动的开始时间 long startTime = System.nanoTime(); // 1.创建引导上下文,用于管理应用启动时的依赖和资源 DefaultBootstrapContext bootstrapContext = createBootstrapContext(); ConfigurableApplicationContext context = null; // 配置无头模式属性,以支持在无图形环境下运行 // 将系统属性 java.awt.headless 设置为 true configureHeadlessProperty(); // 2.获取Spring应用启动监听器,用于在应用启动的各个阶段执行自定义逻辑 SpringApplicationRunListeners listeners = getRunListeners(args); // 启动开始方法(发布开始事件、通知应用监听器ApplicationListener) listeners.starting(bootstrapContext, this.mainApplicationClass); try { // 3.解析应用参数 ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); // 4.准备应用环境,包括读取配置文件和设置环境变量 ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments); // 配置是否忽略 BeanInfo,以加快启动速度 configureIgnoreBeanInfo(environment); // 5.打印启动Banner Banner printedBanner = printBanner(environment); // 6.创建应用程序上下文 context = createApplicationContext(); // 设置应用启动的上下文,用于监控和管理启动过程 context.setApplicationStartup(this.applicationStartup); // 7.准备应用上下文,包括加载配置、添加 Bean 等 prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner); // 8.刷新上下文,完成 Bean 的加载和依赖注入 refreshContext(context); // 9.刷新后的一些操作,如事件发布等 afterRefresh(context, applicationArguments); // 计算启动应用程序的时间,并记录日志 Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime); if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup); } // 10.通知监听器应用启动完成 listeners.started(context, timeTakenToStartup); // 11.调用应用程序中的 `CommandLineRunner` 或 `ApplicationRunner`,以便执行自定义的启动逻辑 callRunners(context, applicationArguments); } catch (Throwable ex) { // 12.处理启动过程中发生的异常,并通知监听器 handleRunFailure(context, ex, listeners); throw new IllegalStateException(ex); } try { // 13.计算应用启动完成至准备就绪的时间,并通知监听器 Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime); listeners.ready(context, timeTakenToReady); } catch (Throwable ex) { // 处理准备就绪过程中发生的异常 handleRunFailure(context, ex, null); throw new IllegalStateException(ex); } // 返回已启动并准备就绪的应用上下文 return context; } 源码入口 这里核心内容就是new AnnotationConfigServletWebServerApplicationContext() // 6.创建应用程序上下文 context = createApplicationContext(); 无参构造 public class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContext implements AnnotationConfigRegistry { // 用于读取注解的Bean定义读取器 private final AnnotatedBeanDefinitionReader reader; // 用于扫描类路径并注册Bean定义的扫描器 private final ClassPathBeanDefinitionScanner scanner; ... // 无参构造函数 public AnnotationConfigServletWebServerApplicationContext() { // 初始化注解Bean定义读取器 this.reader = new AnnotatedBeanDefinitionReader(this); // 初始化类路径Bean定义扫描器 this.scanner = new ClassPathBeanDefinitionScanner(this); } ... }AnnotationConfigServletWebServerApplicationContext类图如下,其实就是应用上下文核心接口Application的实现类,那么注解Bean定义读取器和类路径Bean定义扫描器构造传入的this即Application。
一、初始化注解Bean定义读取器 public class AnnotatedBeanDefinitionReader { // Bean定义注册表,用于管理和注册Bean定义 private final BeanDefinitionRegistry registry; // 条件评估器,用于判断是否满足某些条件 private ConditionEvaluator conditionEvaluator; // 构造方法,接收BeanDefinitionRegistry作为参数 public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) { // 调用带有Environment参数的构造方法,环境对象通过注册表自动创建 this(registry, getOrCreateEnvironment(registry)); } // 构造方法,接收BeanDefinitionRegistry和Environment作为参数 public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { // 校验参数,确保注册表和环境不为空 Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); Assert.notNull(environment, "Environment must not be null"); // 初始化Bean定义注册表 this.registry = registry; // 初始化条件评估器 this.conditionEvaluator = new ConditionEvaluator(registry, environment, null); // 注册注解配置处理器,用于处理注解配置 AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); } ... } 1、BeanDefinitionRegistry(Bean定义注册接口)这里的Bean定义注册表BeanDefinitionRegistry就是AnnotatedBeanDefinitionReader构造传入的AnnotationConfigServletWebServerApplicationContext。
BeanDefinitionRegistry是Spring容器中用于管理Bean定义的核心接口,支持动态注册、移除、查询和别名管理,常用于扩展和动态操作容器内的 Bean 定义。
// 此接口是 Bean 定义注册的核心,用于动态管理 Bean 定义(注册、移除、查询等) public interface BeanDefinitionRegistry extends AliasRegistry { // 向注册表中注册一个新的 BeanDefinition void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException; // 移除给定名称的 BeanDefinition void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; // 返回给定名称的 BeanDefinition BeanDefinition 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); } 2、获取环境对象Environment // AnnotatedBeanDefinitionReader类方法 private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) { // 校验注册表对象不为空 Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); // 如果注册表实现了EnvironmentCapable接口,则直接获取其中的Environment if (registry instanceof EnvironmentCapable) { return ((EnvironmentCapable) registry).getEnvironment(); } // 如果注册表不具备Environment,则创建并返回一个标准的Environment对象 return new StandardEnvironment(); }在创建应用上下文之前,SpringBoot源码解析(五):准备应用环境中有详细介绍应用环境Environment的初始化。
3、注册注解配置处理器 public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) { // 获取默认的ListableBeanFactory对象 // 这里获取到的就是应用上下文中AnnotationConfigServletWebServerApplicationContext的 // 父类GenericApplicationContext的构造中new DefaultListableBeanFactory() DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry); if (beanFactory != null) { // AnnotationAwareOrderComparator:这是一个带有注解感知的比较器,用来排序Bean的依赖 // 它比标准的比较器多了对@Order注解的支持,可以确保按照注解指定的优先级排序依赖关系 if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) { beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE); } // ContextAnnotationAutowireCandidateResolver:这个解析器是用于处理基于注解的自动注入(例如@Autowired注解) // 它负责在自动注入过程中,决定哪些Bean可以作为自动注入的候选者 if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) { beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver()); } } // 创建一个 LinkedHashSet 用于存储 BeanDefinitionHolder // BeanDefinitionHolder: 用于持有 BeanDefinition 及其名称和别名 Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8); // 注册 ConfigurationClassPostProcessor,用于处理 @Configuration 注解 if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); // 注册后置处理器就是将Bean定义添加到bean工厂beanDefinitionMap缓存中,下面细说 beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 注册 AutowiredAnnotationBeanPostProcessor,用于处理 @Autowired 注解 if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 如果 JSR-250 支持存在,注册 CommonAnnotationBeanPostProcessor,用于处理 @Resource 等注解 if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 如果 JPA 支持存在,注册 PersistenceAnnotationBeanPostProcessor,用于处理 JPA 相关的注解 // JPA是一个 Java 标准规范,用于简化对象与关系数据库之间的映射和数据持久化操作 if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(); try { def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, AnnotationConfigUtils.class.getClassLoader())); } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex); } def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)); } // 注册 EventListenerMethodProcessor,用于处理 @EventListener 注解 if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME)); } // 注册 DefaultEventListenerFactory 是事件监听器的工厂类,它实际负责创建监听器对象并将其注册到 Spring 的事件发布机制中 // 当 EventListenerMethodProcessor 找到带有 @EventListener 注解的方法时,它会通过 DefaultEventListenerFactory 创建该方法对应的监听器 if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME)); } // 返回所有注册的 BeanDefinitionHolder return beanDefs; } 3.1、获取默认Bean工厂这里的registry就是注解应用上下文AnnotationConfigServletWebServerApplicationContext,从上面的类图可知GenericApplicationContext是父类之一。
// AnnotationConfigUtils类方法 @Nullable private static DefaultListableBeanFactory unwrapDefaultListableBeanFactory(BeanDefinitionRegistry registry) { if (registry instanceof DefaultListableBeanFactory) { return (DefaultListableBeanFactory) registry; } else if (registry instanceof GenericApplicationContext) { return ((GenericApplicationContext) registry).getDefaultListableBeanFactory(); } else { return null; } }DefaultListableBeanFactory是Spring框架中的一个核心类,负责管理和创建应用上下文中的所有Bean,提供了Bean定义的注册、查找和生命周期管理功能。
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable { // ==================== 核心属性 ==================== // 存储所有注册的 BeanDefinition,键为 beanName,值为对应的 BeanDefinition private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256); // 记录所有注册的beanName,保持注册顺序(通过配置文件、注解、或约定方式将 Bean 注册到容器中,由 Spring 自动完成) private volatile List<String> beanDefinitionNames = new ArrayList<>(256); ... }获取到默认Bean工厂以后,设置了两个重要属性
AnnotationAwareOrderComparator:这是一个带有注解感知的比较器,用来排序Bean的依赖。它比标准的比较器多了对@Order注解的支持,可以确保按照注解指定的优先级排序依赖关系。
ContextAnnotationAutowireCandidateResolver:这个解析器是用于处理基于注解的自动注入(例如@Autowired注解)。它负责在自动注入过程中,决定哪些Bean可以作为自动注入的候选者。
3.2、注册后置处理器(注册Bean定义)上面创建了很多RootBeanDefinition,这些Bean定义只做Spring内部使用,用于处理注解配置
ConfigurationClassPostProcessor,用于处理@Configuration、@Bean、@Import、@ComponentScan等注解AutowiredAnnotationBeanPostProcessor,用于处理@Autowired、@Value注解CommonAnnotationBeanPostProcessor,用于处理@PostConstruct、@PreDestroy、@Resource注解EventListenerMethodProcessor,用于处理@EventListener注解创建完RootBeanDefinition后,还需要将其添加到应用上下文的缓存中
Bean定义的角色设置为2,表示框架内部的实现类,用户无需关心,平常我们创建的组件默认角色就是0,用于实现具体的业务逻辑。
// AnnotationConfigUtils类方法 private static BeanDefinitionHolder registerPostProcessor( BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) { definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); // 注册Bean定义 registry.registerBeanDefinition(beanName, definition); return new BeanDefinitionHolder(definition, beanName); }BeanDefinitionRegistry registry是应用上下文,调用注册Bean定义方法registerBeanDefinition,实际就是调用默认Bean工厂的注册Bean定义的方法,上面有提到默认Bean工厂DefaultListableBeanFactory核心属性beanDefinitionMap就是存储所有注册的BeanDefinition。
二、初始化类路径Bean定义扫描器 1、注册默认注解过滤器通过ClassPathBeanDefinitionScanner的构造方法,最终跳转到最后一个构造方法,核心操作是注册默认的注解扫描过滤器。
注册默认的注解过滤器,确保在组件扫描时,能够识别特定的注解。添加@Component注解的过滤器,允许扫描带有@Component注解的类,@Controller 、@Service、 @Repository也会被扫描到。
// ClassPathScanningCandidateComponentProvider类方法 protected void registerDefaultFilters() { // 添加 @Component 注解的过滤器,允许扫描带有 @Component 注解的类 this.includeFilters.add(new AnnotationTypeFilter(Component.class)); // @Component 是 Spring 框架的通用组件注解(只关心这个就可以) // @ManagedBean 是 Java EE 的托管 Bean 注解 // 而 @Named 是 CDI(Jakarta EE)的标准化注解 // 获取类加载器 ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader(); try { // 尝试加载 javax.annotation.ManagedBean 注解类,如果存在,添加为过滤器 this.includeFilters.add(new AnnotationTypeFilter( ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false)); logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning"); } catch (ClassNotFoundException ex) { // 如果 JSR-250 API 未找到,跳过该注解支持 } try { // 尝试加载 javax.inject.Named 注解类,如果存在,添加为过滤器 this.includeFilters.add(new AnnotationTypeFilter( ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false)); logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning"); } catch (ClassNotFoundException ex) { // 如果 JSR-330 API 未找到,跳过该注解支持 } } 2、自定义包扫描此方法将在后续通过传入包路径调用,并返回注册的Bean定义集合。具体源码后续调用时候详细
protected Set<BeanDefinitionHolder> doScan(String... basePackages) { // 检查 basePackages 是否为空,如果为空则抛出异常 Assert.notEmpty(basePackages, "At least one base package must be specified"); // 用于存储扫描到的 Bean 定义 Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>(); // 遍历传入的每个包路径进行扫描 for (String basePackage : basePackages) { // 查找当前包路径下符合条件的候选组件 Set<BeanDefinition> candidates = findCandidateComponents(basePackage); // 遍历候选组件 for (BeanDefinition candidate : candidates) { // 获取该 Bean 定义的作用域元数据,并设置作用域 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName()); // 生成 Bean 的名称 String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); // 如果候选 Bean 是 AbstractBeanDefinition 类型,进行后处理 if (candidate instanceof AbstractBeanDefinition) { postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } // 如果候选 Bean 是 AnnotatedBeanDefinition 类型,处理注解配置 if (candidate instanceof AnnotatedBeanDefinition) { AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } // 如果当前 Bean 名称和定义符合要求,则继续处理 if (checkCandidate(beanName, candidate)) { // 创建一个 BeanDefinitionHolder 来包装 Bean 定义和 Bean 名称 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); // 根据作用域元数据,可能应用代理模式 definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); // 将处理好的 Bean 定义添加到集合中 beanDefinitions.add(definitionHolder); // 将 Bean 定义注册到容器中 registerBeanDefinition(definitionHolder, this.registry); } } } // 返回所有注册的 Bean 定义 return beanDefinitions; } 总结本文详细介绍了SpringBoot应用上下文AnnotationConfigServletWebServerApplicationContext的构造方法中初始化两个重要组件:一是注解Bean定义读取器,创建一些特殊Bean定义(Spring内部使用,也叫后置处理器),用于处理@Configuration、@Autowired等注解;二是类路径Bean定义扫描器,用于扫描给定路径下的@Component注解组件,将其转换为Bean定义。
SpringBoot源码解析(十):应用上下文AnnotationConfigServletWebServerA由讯客互联开源代码栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“SpringBoot源码解析(十):应用上下文AnnotationConfigServletWebServerA”