SpringBoot 源码解析:应用上下文构造流程
在 SpringBoot 启动流程中,创建应用程序上下文是核心环节之一。本文聚焦于 createApplicationContext() 方法的具体实现,深入分析 AnnotationConfigServletWebServerApplicationContext 的初始化过程。
源码入口
在 SpringApplication.run() 方法的执行逻辑中,第 6 步负责创建应用程序上下文:
// SpringApplication 类方法
public ConfigurableApplicationContext run(String... args) {
// ... 前置步骤 ...
// 6. 创建应用程序上下文
context = createApplicationContext();
// ... 后续步骤 ...
}
核心代码即实例化 AnnotationConfigServletWebServerApplicationContext:
public class AnnotationConfigServletWebServerApplicationContext
extends ServletWebServerApplicationContext implements AnnotationConfigRegistry {
private final AnnotatedBeanDefinitionReader reader;
private final ClassPathBeanDefinitionScanner scanner;
public AnnotationConfigServletWebServerApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
}
这里初始化了两个关键组件:注解 Bean 定义读取器(reader)和类路径 Bean 定义扫描器(scanner)。它们都接收当前上下文实例作为参数,用于后续的 Bean 注册与管理。
一、初始化注解 Bean 定义读取器
AnnotatedBeanDefinitionReader 负责处理带有注解的配置类。其构造函数主要完成三件事:获取注册表、获取环境对象、注册配置处理器。
1. Bean 定义注册接口
构造时传入的 this 即为 AnnotationConfigServletWebServerApplicationContext,它实现了 BeanDefinitionRegistry 接口。该接口是容器管理 Bean 定义的核心,支持动态注册、移除和查询。
public interface BeanDefinitionRegistry extends AliasRegistry {
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);
void removeBeanDefinition(String beanName);
BeanDefinition getBeanDefinition(String beanName);
// ... 其他方法
}
2. 获取环境对象 Environment
环境对象是配置信息的载体。如果注册表实现了 EnvironmentCapable 接口,则直接获取;否则创建默认的 StandardEnvironment。
private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
if (registry instanceof EnvironmentCapable) {
return ((EnvironmentCapable) registry).getEnvironment();
}
return new StandardEnvironment();
}
3. 注册注解配置处理器
这是初始化的关键步骤。系统会自动注册一系列后置处理器(PostProcessor),用于处理不同类型的注解。
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
// 设置依赖比较器,支持 @Order 注解排序
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
// 设置自动注入候选解析器
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// 注册 ConfigurationClassPostProcessor,处理 @Configuration, @Bean 等
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 注册 AutowiredAnnotationBeanPostProcessor,处理 @Autowired, @Value
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));
}
// 注册 CommonAnnotationBeanPostProcessor,处理 @Resource, @PostConstruct
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));
}
// 注册 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));
}
return beanDefs;
}
这些处理器主要用于框架内部,角色被标记为 ROLE_INFRASTRUCTURE(基础设施),用户通常无需干预。
二、初始化类路径 Bean 定义扫描器
ClassPathBeanDefinitionScanner 负责扫描指定包路径下的组件,将其转换为 Bean 定义并注册到容器中。
1. 注册默认注解过滤器
扫描器初始化时会加载默认过滤器,确保能识别常见的 Spring 组件注解。
protected void registerDefaultFilters() {
// 添加 @Component 注解的过滤器
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
// 尝试加载 JSR-250 和 CDI 相关注解,若存在则支持
try {
this.includeFilters.add(new AnnotationTypeFilter(ClassUtils.forName("javax.annotation.ManagedBean", cl), false));
} catch (ClassNotFoundException ex) { /* 忽略 */ }
try {
this.includeFilters.add(new AnnotationTypeFilter(ClassUtils.forName("javax.inject.Named", cl), false));
} catch (ClassNotFoundException ex) { /* 忽略 */ }
}
这意味着带有 @Component, @Controller, @Service, @Repository 的类都会被纳入扫描范围。
2. 自定义包扫描
当调用 doScan 方法时,会遍历指定包路径,查找符合条件的候选组件。
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
在此过程中,系统会处理作用域元数据、生成 Bean 名称、应用代理模式,并最终将 Bean 定义注册到容器的 beanDefinitionMap 缓存中。
总结
AnnotationConfigServletWebServerApplicationContext 的构造过程主要完成了两件事:
- 初始化注解 Bean 定义读取器:注册各类后置处理器(如
ConfigurationClassPostProcessor,AutowiredAnnotationBeanPostProcessor等),为后续注解解析打下基础。 - 初始化类路径 Bean 定义扫描器:配置默认过滤器,准备扫描指定包路径下的组件并将其注册为 Bean。
这两个组件构成了 SpringBoot Web 应用上下文的基石,确保了从配置类解析到组件扫描的全流程顺畅运行。


