跳到主要内容SpringBoot 源码解析:AnnotationConfigServletWebServerApplicationContext 构造流程 | 极客日志Javajava
SpringBoot 源码解析:AnnotationConfigServletWebServerApplicationContext 构造流程
SpringBoot 启动时创建应用上下文是核心环节。本文深入剖析 AnnotationConfigServletWebServerApplicationContext 的构造过程,重点讲解注解 Bean 定义读取器与类路径扫描器的初始化机制。通过源码分析,揭示了后置处理器如 ConfigurationClassPostProcessor 的注册原理及组件扫描过滤器的配置逻辑,帮助理解 Spring 容器如何加载并管理 Bean 定义。
SpringBoot 源码解析:AnnotationConfigServletWebServerApplicationContext 构造流程
在 SpringBoot 启动过程中,创建应用程序上下文是核心环节之一。本文聚焦于 AnnotationConfigServletWebServerApplicationContext 的构造方法,深入剖析其内部组件初始化的逻辑细节。
源码入口
在 SpringApplication.run() 方法的执行链路中,第 6 步负责创建应用程序上下文:
public ConfigurableApplicationContext run(String... args) {
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
该类实现了 Application 接口,构造时传入的 this 即应用上下文实例。下图展示了其继承体系结构:
一、初始化注解 Bean 定义读取器
构造 AnnotatedBeanDefinitionReader 时,主要完成三件事:获取注册表、获取环境对象、注册后置处理器。
public class AnnotatedBeanDefinitionReader {
private final BeanDefinitionRegistry registry;
private ConditionEvaluator conditionEvaluator;
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
}
1. BeanDefinitionRegistry(Bean 定义注册接口)
这里的 registry 参数实际上就是当前应用上下文 AnnotationConfigServletWebServerApplicationContext 本身。它是 Spring 容器管理 Bean 定义的核心接口,支持动态注册、移除和查询。
public interface BeanDefinitionRegistry extends AliasRegistry {
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);
void removeBeanDefinition(String beanName);
BeanDefinition getBeanDefinition(String beanName);
boolean containsBeanDefinition(String beanName);
String[] getBeanDefinitionNames();
int getBeanDefinitionCount();
boolean isBeanNameInUse(String beanName);
}
2. 获取环境对象 Environment
环境对象通过注册表自动创建或获取。如果注册表实现了 EnvironmentCapable 接口,则直接调用;否则创建标准环境。
private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry instanceof EnvironmentCapable) {
return ((EnvironmentCapable) registry).getEnvironment();
}
return new StandardEnvironment();
}
3. 注册注解配置处理器
这是构造过程中的关键步骤,系统会自动注册一系列处理特定注解的后置处理器。
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
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));
}
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));
}
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));
}
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;
}
3.1 获取默认 Bean 工厂
通过 unwrapDefaultListableBeanFactory 方法从注册表中提取 DefaultListableBeanFactory。该工厂负责管理容器中所有 Bean 的定义与生命周期。
@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;
}
}
- AnnotationAwareOrderComparator:支持
@Order 注解的依赖排序比较器。
- ContextAnnotationAutowireCandidateResolver:处理基于注解的自动注入候选者解析。
3.2 注册后置处理器(注册 Bean 定义)
上述代码中创建的 RootBeanDefinition 主要用于 Spring 内部处理注解配置。注册时需将角色设置为 ROLE_INFRASTRUCTURE(基础设施),区别于用户业务 Bean 的 ROLE_APPLICATION。
private static BeanDefinitionHolder registerPostProcessor(
BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(beanName, definition);
return new BeanDefinitionHolder(definition, beanName);
}
ConfigurationClassPostProcessor:处理 @Configuration, @Bean, @Import, @ComponentScan。
AutowiredAnnotationBeanPostProcessor:处理 @Autowired, @Value。
CommonAnnotationBeanPostProcessor:处理 @PostConstruct, @PreDestroy, @Resource。
EventListenerMethodProcessor:处理 @EventListener。
二、初始化类路径 Bean 定义扫描器
ClassPathBeanDefinitionScanner 负责扫描指定包路径下的组件类。
1. 注册默认注解过滤器
扫描器初始化时会注册默认的过滤规则,确保能识别标准的 Spring 组件注解。
protected void registerDefaultFilters() {
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
} catch (ClassNotFoundException ex) {
}
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
} catch (ClassNotFoundException ex) {
}
}
2. 自定义包扫描
当调用扫描方法时,会遍历指定包路径,查找符合条件的候选组件并注册到容器中。
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;
}
总结
本文详细拆解了 AnnotationConfigServletWebServerApplicationContext 构造过程中的核心逻辑。主要包括两部分:一是初始化注解 Bean 定义读取器,注册各类后置处理器以支持注解解析;二是初始化类路径 Bean 定义扫描器,配置默认过滤器以便后续组件扫描。理解这一过程有助于掌握 SpringBoot 容器启动及 Bean 加载的底层机制。
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online