上一篇讲到Spring boot的常见容器,大部分Spring boot运用都没有启用AOT模式,现在看一下没有启用AOT模式的条件下如何加载和注册Spring 内部的 BeanDefinition,主配置类的加载和注册已经在这篇提到
BeanDefinitionRegistry
接口BeanDefinitionRegistry 是 Spring 框架中用于管理 Bean 定义(BeanDefinition) 的核心接口,其作用是提供对 Bean 定义的注册、查询、删除等操作。它是 Spring IOC 容器构建过程中非常关键的一环。
/**
* 在此注册表中注册一个新的 Bean 定义。
* 必须支持 RootBeanDefinition 和 ChildBeanDefinition 类型。
*
* @param beanName 要注册的 Bean 实例的名称
* @param beanDefinition 要注册的 Bean 的定义信息
* @throws BeanDefinitionStoreException 如果 Bean 定义无效,抛出此异常
* @throws BeanDefinitionOverrideException 如果已经存在相同名称的 Bean 定义,
* 并且不允许覆盖,则抛出此异常
*
* @see GenericBeanDefinition
* @see RootBeanDefinition
* @see ChildBeanDefinition
*/
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
实现类 | 描述 |
---|---|
DefaultListableBeanFactory | 标准的 BeanFactory 实现,内部维护完整的 Bean 定义集合,支持注册、查找和依赖注入 |
GenericApplicationContext |
通用应用上下文实现,封装了 BeanFactory 和环境配置,包含DefaultListableBeanFactory |
GenericApplicationContext
容器GenericApplicationContext 是 Spring 框架中一个通用的、可编程的应用上下文实现类,位于 org.springframework.context.support 包中。它的主要作用是提供一个轻量级的容器环境,用于注册和管理 Bean 定义,并支持通过不同的配置方式(如 XML、Java 注解、Properties 等)加载 Bean。
private final DefaultListableBeanFactory beanFactory;
/**
* Create a new GenericApplicationContext.
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}
BeanDefinition
最终使用DefaultListableBeanFactory
注册实现类 | 描述 |
---|---|
AnnotationConfigApplicationContext | 使用注解驱动,依赖运行时反射 |
AnnotationConfigServletWebServerApplicationContext | 使用注解驱动,支持 Web 应用,依赖运行时反射 |
AnnotationConfigReactiveWebServerApplicationContext | 使用注解驱动,支持响应式 Web,依赖运行时反射 |
常见Spring boot创建的容器都会继承GenericApplicationContext
,这使得容器本身也是BeanDefinitionRegistry
,容器最终注册的BeanDefinition
都是到DefaultListableBeanFactory
。
AnnotatedBeanDefinitionReader
类在容器的构造函数中创建
this.reader = new AnnotatedBeanDefinitionReader(this);
this
就是容器,容器当作了BeanDefinitionRegistry
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)
/**
* 为给定的注册表创建一个新的 AnnotatedBeanDefinitionReader。
*
* 如果该注册表实现了 {@link EnvironmentCapable} 接口(例如一个应用上下文),
* 则会继承其环境配置;否则将创建并使用一个新的 {@link StandardEnvironment} 环境对象。
*
* @param registry 要加载 Bean 定义的目标 BeanFactory,以 {@code BeanDefinitionRegistry} 的形式提供
* @see #AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment)
* @see #setEnvironment(Environment)
*/
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
/**
* 使用指定的环境配置,为给定的注册表创建一个新的 AnnotatedBeanDefinitionReader。
*
* @param registry 要加载 Bean 定义的目标 BeanFactory,以 {@code BeanDefinitionRegistry} 的形式提供
* @param environment 在评估 Bean 定义配置文件(profile)时使用的环境对象
* @since 3.1
*/
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry 必须不为空");
Assert.notNull(environment, "Environment 必须不为空");
this.registry = registry;
// 创建条件评估器,用于处理 @Conditional 注解等逻辑
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
// 注册 Spring 内部用于处理注解配置的处理器(如 ConfigurationClassPostProcessor)
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
AnnotatedBeanDefinitionReader
构造函数中的registry
就是容器本身AnnotatedBeanDefinitionReader
注册的BeanDefinition
放到容器中AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)
方法,核心是注册 ConfigurationClassPostProcessor
/**
* 在给定的注册表中注册所有相关的注解后处理器(Annotation Post Processors)。
*
* @param registry 要操作的 BeanDefinitionRegistry 注册表
*/
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
/**
* 在给定的注册表中注册所有相关的注解后处理器。
*
* @param registry 要操作的 BeanDefinitionRegistry 注册表
* @param source 触发此次注册的配置源对象(可为 null)
* @return 返回一个包含所有实际注册的 Bean 定义的 Set 集合
*/
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 尝试获取底层使用的 DefaultListableBeanFactory 实例
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
// 如果依赖排序器不是 AnnotationAwareOrderComparator,则设置它
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
// 如果自动装配候选解析器不是 ContextAnnotationAutowireCandidateResolver,则设置默认的
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
// 创建用于存储已注册 Bean 定义的集合
Set<BeanDefinitionHolder> beanDefs = CollectionUtils.newLinkedHashSet(6);
// 注册 ConfigurationClassPostProcessor,用于处理 @Configuration 类
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));
}
// 检查是否引入了 Jakarta 注解支持,如果存在则注册 CommonAnnotationBeanPostProcessor
// 用于处理 @Resource、@PostConstruct、@PreDestroy 等注解
if (jakartaAnnotationsPresent && !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 相关注解如 @PersistenceContext、@PersistenceUnit
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(
"无法加载可选框架类: " + 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,用于创建监听事件的工厂类
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));
}
return beanDefs;
}
registerAnnotationConfigProcessors(BeanDefinitionRegistry registry)
null
作为配置源。registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source)
后处理器 | 对应注解/功能 | 说明 |
---|---|---|
ConfigurationClassPostProcessor |
@Configuration , @ComponentScan , @Import 等 |
处理基于 Java 配置类的 Bean 定义 |
AutowiredAnnotationBeanPostProcessor |
@Autowired , @Value |
处理自动注入逻辑 |
CommonAnnotationBeanPostProcessor |
@Resource , @PostConstruct , @PreDestroy |
处理 Jakarta EE 标准注解 |
PersistenceAnnotationBeanPostProcessor |
@PersistenceContext , @PersistenceUnit |
支持 JPA 注解处理 |
EventListenerMethodProcessor |
@EventListener |
注册监听方法为 ApplicationListener |
DefaultEventListenerFactory |
N/A | 工厂类,用于创建事件监听器 |
Spring boot创建容器的时候就已经注册一堆后处理器,这些后处理器将在AbstractApplicationContext.refresh()
起作用
refresh
SpringApplication.run()
方法,核心是refreshContext(context)
方法/**
* 运行 Spring 应用程序,创建并刷新一个新的 {@link ApplicationContext}(应用上下文)。
*
* 该方法会执行以下主要步骤:
* 1. 创建启动策略(Startup)实例;
* 2. 注册关闭钩子(如果启用);
* 3. 准备引导上下文(BootstrapContext);
* 4. 配置 headless 属性;
* 5. 获取运行监听器并通知 starting 事件;
* 6. 准备环境配置(Environment);
* 7. 打印 Banner;
* 8. 创建应用上下文;
* 9. 准备上下文环境;
* 10. 刷新上下文;
* 11. 调用 ApplicationRunner 和 CommandLineRunner;
* 12. 处理异常和失败情况;
* 13. 最后通知 listeners 应用已就绪。
*
* @param args 应用程序参数(通常由 main 方法传入)
* @return 已经运行的 {@link ConfigurableApplicationContext}
*/
public ConfigurableApplicationContext run(String... args) {
// 创建启动策略(用于处理启动指标)
Startup startup = Startup.create();
// 如果启用了注册关闭钩子,则启用它
if (this.properties.isRegisterShutdownHook()) {
SpringApplication.shutdownHook.enableShutdownHookAddition();
}
// 创建默认的 Bootstrap 上下文
DefaultBootstrapContext bootstrapContext = createBootstrapContext();
// 初始化可配置的应用上下文为 null
ConfigurableApplicationContext context = null;
// 配置 headless 模式(默认为 true)
configureHeadlessProperty();
// 获取运行监听器并触发 starting 事件
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
// 封装应用程序参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 准备环境配置(包括系统环境、JVM 参数等)
ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
// 打印 Banner(控制台或日志)
Banner printedBanner = printBanner(environment);
// 创建应用上下文(根据 WebApplicationType 决定类型)
context = createApplicationContext();
// 设置应用启动监控
context.setApplicationStartup(this.applicationStartup);
// 准备应用上下文环境(设置 BeanFactoryPostProcessors、ResourceLoader 等)
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
// 刷新上下文(加载 Bean 定义、初始化单例 Bean)
refreshContext(context);
// 刷新后处理(子类扩展点)
afterRefresh(context, applicationArguments);
// 记录启动耗时
startup.started();
// 如果启用了启动日志,记录启动完成信息
if (this.properties.isLogStartupInfo()) {
new StartupInfoLogger(this.mainApplicationClass, environment).logStarted(getApplicationLog(), startup);
}
// 通知监听器上下文已启动
listeners.started(context, startup.timeTakenToStarted());
// 调用所有 ApplicationRunner 和 CommandLineRunner
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
// 处理运行时异常
throw handleRunFailure(context, ex, listeners);
}
try {
// 如果上下文正在运行,通知监听器应用已准备就绪
if (context.isRunning()) {
listeners.ready(context, startup.ready());
}
}
catch (Throwable ex) {
// 处理就绪阶段的异常
throw handleRunFailure(context, ex, null);
}
// 返回运行中的上下文
return context;
}
createApplicationContext()
ConfigurationClassPostProcessor
。prepareContext(...)
内部的后处理器
和 主配置类
将在 refreshContext(context)
起作用
SpringApplication.refreshContext()
方法private void refreshContext(ConfigurableApplicationContext context) {
if (this.properties.isRegisterShutdownHook()) {
shutdownHook.registerApplicationContext(context);
}
refresh(context);
}
/**
* Refresh the underlying {@link ApplicationContext}.
* @param applicationContext the application context to refresh
*/
protected void refresh(ConfigurableApplicationContext applicationContext) {
applicationContext.refresh();
}
applicationContext.refresh()
最终调用的是 AbstractApplicationContext.refresh()
AbstractApplicationContext.refresh()
方法,核心是invokeBeanFactoryPostProcessors(beanFactory)
/**
* 刷新此应用程序上下文,包括 BeanFactory 的创建、配置、刷新以及相关组件的初始化。
* 此方法会加载所有单例 bean 并发布相应的事件。
*
* @throws BeansException 如果在初始化过程中发生 bean 相关错误
* @throws IllegalStateException 如果上下文状态不正确(例如已关闭)
*/
public void refresh() throws BeansException, IllegalStateException {
// 加锁以确保线程安全地执行刷新操作
this.startupShutdownLock.lock();
try {
// 记录当前线程为启动/关闭线程
this.startupShutdownThread = Thread.currentThread();
// 启动应用启动性能追踪步骤
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 1. 准备刷新:设置启动时间、激活标志、验证环境属性等
prepareRefresh();
// 2. 获取或刷新内部的 BeanFactory 实例(由子类实现)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3. 对 BeanFactory 进行基本配置,如类加载器、表达式解析器、注册一些基础的后处理器等
prepareBeanFactory(beanFactory);
try {
// 4. 允许子类对 BeanFactory 做进一步的定制化处理(模板方法)
postProcessBeanFactory(beanFactory);
// 启动 Bean 后处理器相关的性能追踪步骤
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// 5. 调用所有已注册的 BeanFactoryPostProcessor 来修改 BeanFactory 配置
invokeBeanFactoryPostProcessors(beanFactory);
// 6. 注册 BeanPostProcessor,用于拦截 bean 的创建过程
registerBeanPostProcessors(beanFactory);
// 结束 Bean 后处理器的性能追踪步骤
beanPostProcess.end();
// 7. 初始化消息源(MessageSource),用于国际化支持
initMessageSource();
// 8. 初始化事件广播器(ApplicationEventMulticaster),用于事件发布
initApplicationEventMulticaster();
// 9. 模板方法,允许子类初始化特定上下文中的其他特殊 bean
onRefresh();
// 10. 注册监听器,包括静态监听器和 Bean 类型的监听器
registerListeners();
// 11. 完成 BeanFactory 的初始化,实例化所有非懒加载的单例 bean
finishBeanFactoryInitialization(beanFactory);
// 12. 完成刷新,重置缓存、发布 ContextRefreshedEvent 事件
finishRefresh();
}
catch (RuntimeException | Error ex) {
// 异常处理:记录日志、销毁已创建的单例、取消刷新、抛出异常
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁已创建的单例,避免资源泄漏
destroyBeans();
// 重置 active 标志
cancelRefresh(ex);
// 抛出异常给调用者
throw ex;
}
finally {
// 结束上下文刷新的性能追踪步骤
contextRefresh.end();
}
}
finally {
// 清理启动/关闭线程引用,并释放锁
this.startupShutdownThread = null;
this.startupShutdownLock.unlock();
}
}
准备阶段:
BeanFactory 创建与配置:
obtainFreshBeanFactory()
方法:子类负责创建一个新的 beanFactory
,这里的子类是 GenericApplicationContext
,beanFactory
自然就是DefaultListableBeanFactory
;BeanPostProcessor
和依赖解析策略。BeanFactory 后处理:
BeanFactoryPostProcessor
;BeanPostProcessor
;Bean 实例化:
完成刷新:
ContextRefreshedEvent
事件;AbstractApplicationContext.invokeBeanFactoryPostProcessors(...)
方法,核心是PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(...)
/**
* 实例化并调用所有已注册的 BeanFactoryPostProcessor bean。
* 如果指定了顺序,会尊重该顺序进行调用。
*
* 注意:该方法必须在单例 bean 实例化之前调用。
*
* @param beanFactory 要操作的 BeanFactory
*/
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 使用 PostProcessorRegistrationDelegate 工具类来调用所有的 BeanFactoryPostProcessor
// 这些处理器可以修改 BeanFactory 的配置,例如添加额外的 BeanDefinition
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// 检查是否已经定义了 LoadTimeWeaver(例如通过 @Bean 方法由 ConfigurationClassPostProcessor 注册)
// 如果发现 LoadTimeWeaver,则准备进行加载时织入(Load-Time Weaving)
if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null &&
beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
// 添加 LoadTimeWeaverAwareProcessor,用于处理实现了 LoadTimeWeaverAware 接口的 bean
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// 设置一个临时的 ClassLoader,用于类型匹配
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
beanFactory
是 DefaultListableBeanFactory
,DefaultListableBeanFactory
实现BeanDefinitionRegistry
接口。BeanFactoryPostProcessor
,包括:
ConfigurationClassPostProcessor
(负责处理 @Configuration
类)。PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(...)
方法/**
* 调用所有已注册的 BeanFactoryPostProcessor。
* 包括通过上下文显式传入的处理器(beanFactoryPostProcessors),
* 以及容器中定义为 bean 的 BeanFactoryPostProcessor 实例。
*
* 此方法会优先处理 BeanDefinitionRegistryPostProcessor,
* 因为其可以修改 BeanDefinition 注册信息。
*
*
调用顺序遵循以下优先级规则:
* 1. 实现 PriorityOrdered 接口的处理器;
* 2. 实现 Ordered 接口的处理器;
* 3. 其他无排序接口的处理器。
*
* @param beanFactory 当前应用上下文使用的 BeanFactory
* @param beanFactoryPostProcessors 上下文显式注册的 BeanFactoryPostProcessor 列表
*/
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory,
List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 注意:虽然看起来可以简化多层循环和多个列表的操作,但这样做是故意设计的。
// 必须确保按照 PriorityOrdered 和 Ordered 的契约正确执行后处理器。
// 修改此方法前,请查看 Spring 官方仓库中被拒绝的相关 PR,避免引入破坏性变更。
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry registry) {
// 如果是 BeanDefinitionRegistry 类型,则先处理 BeanDefinitionRegistryPostProcessor
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 遍历显式传入的 postProcessors,区分出 BeanDefinitionRegistryPostProcessor
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor registryProcessor) {
// 直接调用其 postProcessBeanDefinitionRegistry 方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
regularPostProcessors.add(postProcessor);
}
}
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 第一步:调用实现 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor
// 从 beanFactory 获取 BeanDefinitionRegistryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 通过 beanFactory.getBean() 真正创建 BeanDefinitionRegistryPostProcessor 实例
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 调用 BeanDefinitionRegistryPostProcessor
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// 第二步:调用实现 Ordered 接口的 BeanDefinitionRegistryPostProcessor
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
// 通过 beanFactory.getBean() 真正创建 BeanDefinitionRegistryPostProcessor 实例
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 调用 BeanDefinitionRegistryPostProcessor
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// 第三步:调用其余未处理的 BeanDefinitionRegistryPostProcessor,直到没有新的出现
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
// 通过 beanFactory.getBean() 真正创建 BeanDefinitionRegistryPostProcessor 实例
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true; // 如果新增了处理器,继续循环
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 调用 BeanDefinitionRegistryPostProcessor
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}
// 最后再统一调用这些处理器的 postProcessBeanFactory 方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// 如果不是 BeanDefinitionRegistry 类型,直接调用传入的 BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 再次查找并调用其他 BeanFactoryPostProcessor(非 BeanDefinitionRegistryPostProcessor)
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// 已经在上面处理过,跳过
continue;
}
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 第一步:调用实现 PriorityOrdered 的 BeanFactoryPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 第二步:调用实现 Ordered 的 BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// 第三步:调用其余无序的 BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// 清除缓存的合并 BeanDefinition,因为可能已被修改(如占位符替换等)
beanFactory.clearMetadataCache();
}
beanFactory instanceof BeanDefinitionRegistry
?BeanFactory
都实现BeanDefinitionRegistry
BeanFactory
的核心职责是 管理 Bean 的创建和获取。BeanDefinitionRegistry
的职责是 允许注册新的 Bean 定义(BeanDefinition)
,属于扩展功能。BeanDefinitionRegistry
,可以控制哪些组件能修改容器结构。BeanFactory (DefaultListableBeanFactory)
的BeanDefinition(BeanDefinitionRegistryPostProcessor)
,如 ConfigurationClassPostProcessor
(负责处理 @Configuration
类)。BeanFactory
不是 BeanDefinitionRegistry
,说明 BeanFactory
没有注册任何 BeanDefinition
步骤 | 处理器类型 | 调用顺序 | 特点 |
---|---|---|---|
1 | BeanDefinitionRegistryPostProcessor + PriorityOrdered | 最高优先级 | 可以修改 BeanDefinition 注册 |
2 | BeanDefinitionRegistryPostProcessor + Ordered | 次优先级 | 同上 |
3 | BeanDefinitionRegistryPostProcessor + 无排序 | 默认顺序 | 同上 |
4 | BeanFactoryPostProcessor + PriorityOrdered | 第四优先级 | 修改整个 BeanFactory |
5 | BeanFactoryPostProcessor + Ordered | 第五优先级 | 同上 |
6 | BeanFactoryPostProcessor + 无排序 | 最低优先级 | 同上 |
BeanDefinitionRegistryPostProcessor
再调用BeanFactoryPostProcessor
,否则可能导致配置错误或代理失效;PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(...)
方法/**
* 调用给定的 BeanDefinitionRegistryPostProcessor 实例。
*
* @param postProcessors 一组实现了 BeanDefinitionRegistryPostProcessor 接口的处理器
* @param registry Bean定义注册表,用于注册Bean定义
* @param applicationStartup 用于跟踪应用程序启动步骤的工具
*/
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors,
BeanDefinitionRegistry registry,
ApplicationStartup applicationStartup) {
// 遍历所有的 BeanDefinitionRegistryPostProcessor 实例
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
// 开始一个应用启动步骤,并记录该步骤的相关信息
StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process")
.tag("postProcessor", postProcessor::toString);
// 调用 postProcessBeanDefinitionRegistry 方法,允许处理器对 BeanDefinitionRegistry 进行处理
postProcessor.postProcessBeanDefinitionRegistry(registry);
// 结束当前的应用启动步骤
postProcessBeanDefRegistry.end();
}
}
registry
是 DefaultListableBeanFactory
,DefaultListableBeanFactory
实现BeanDefinitionRegistry
接口。postProcessor.postProcessBeanDefinitionRegistry(registry)
只能使用 DefaultListableBeanFactory
的 BeanDefinitionRegistry
功能PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(...)
方法/**
* 调用给定的 BeanFactoryPostProcessor 实例。
*
* @param postProcessors 一组实现了 BeanFactoryPostProcessor 接口的处理器
* @param beanFactory 当前使用的 BeanFactory 实例,用于配置和管理 Bean
*/
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors,
ConfigurableListableBeanFactory beanFactory) {
// 遍历所有的 BeanFactoryPostProcessor 实例
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
// 启动一个应用启动步骤跟踪(用于性能监控),并附加当前处理器信息
StartupStep postProcessBeanFactory = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process")
.tag("postProcessor", postProcessor::toString);
// 调用 postProcessBeanFactory 方法,允许处理器修改 BeanFactory 的配置
postProcessor.postProcessBeanFactory(beanFactory);
// 结束该启动步骤的跟踪
postProcessBeanFactory.end();
}
}
beanFactory
是 DefaultListableBeanFactory
,DefaultListableBeanFactory
实现BeanDefinitionRegistry
接口。postProcessor.postProcessBeanFactory(beanFactory)
只能使用 DefaultListableBeanFactory
的 BeanFactory
功能