题目:如何根据配置动态生成 Spring 的 Bean?
难度:difficulty/medium
评分:⭐⭐⭐☆☆(3/5)
根据配置动态生成 spring bean 主要有两种:启动阶段批量配置 BeanDefinitionRegistryPostProcessor 来创建;通过 FactoryBean 创建单个的类。
优点:方向对——BDRegistryPostProcessor 批量 + FactoryBean 单个。
不足:过于简略,漏 @Bean+@Configuration、ImportBeanDefinitionRegistrar、ConditionalOnXxx、BeanDefinitionBuilder。
补充:核心场景是"按配置决定是否注册 / 批量注册"。
最后更新:2026-10-27 · 基于第 1 次作答
结论:动态生成 Bean 的本质是在 BeanDefinition 阶段注册元数据,核心接口是 BeanDefinitionRegistryPostProcessor。 关键词:BeanDefinition 先行 · BDRegistryPostProcessor · ImportBeanDefinitionRegistrar 边界:注册必须发生在实例化之前(容器刷新早期)。
核心考点定位:考察 Bean 生命周期早期 + 注册机制。面试官想排除"动态生成 = 直接 new 对象丢给容器"的错误认知。
机制链(≥3 环):
证据锚点(≥10):
BeanDefinitionRegistryPostProcessor:批量注册入口,容器刷新早期回调BeanDefinitionRegistry:注册表,registerBeanDefinition 方法BeanDefinitionBuilder:构建 BeanDefinition 的工具ImportBeanDefinitionRegistrar:@Import 时注册@Import:显式导入类/配置@Bean:配置类方法声明 Bean@ConditionalOnXxx:条件注册(如 @ConditionalOnProperty)@Profile:按环境注册BeanDefinition:Bean 元数据(class/scope/属性)FactoryBean:单点定制创建对比与权衡:
| 方式 | 正确性 | 粒度 | 失败模式 | 适用边界 |
|---|---|---|---|---|
| BDRegistryPostProcessor | 高 | 批量 | 注册时机早 | 按配置批量注册 |
| ImportBeanDefinitionRegistrar | 高 | 模块 | 依赖 @Import | 模块化引入 |
| FactoryBean | 高 | 单点 | 定制复杂 | 第三方类封装 |
| @ConditionalOnXxx | 中 | 单点 | 条件误配 | 开关式组件 |
常见误区:
适用边界:动态注册只适合"启动时已知"的 Bean;运行时动态增减 Bean 不是主流,用 @Lazy/工厂更合适。
【结论】 面试官您好,动态生成 Bean 的本质是在 BeanDefinition 阶段注册元数据,核心接口是 BeanDefinitionRegistryPostProcessor。
【三点】 第一,Spring 先注册 BeanDefinition 再实例化,所以"动态生成"就是提前注册定义,不是直接 new 对象。第二,最常用 BeanDefinitionRegistryPostProcessor——在容器刷新早期遍历配置,用 BeanDefinitionBuilder 构建并 registerBeanDefinition,可批量注册。第三,单点定制用 FactoryBean,按条件生成用 @ConditionalOnXxx / @Profile,模块化引入用 ImportBeanDefinitionRegistrar。
【边界】 当然,动态注册必须发生在实例化之前(容器刷新早期),晚了注册不进去;且批量注册要用 BeanDefinitionBuilder 而不是直接 new。
| # | 日期 | 评分 | 本轮主要问题 | 记录 |
|---|---|---|---|---|
| 1 | 2026-10-27 | 3/5 | 过简,漏 @Bean/@ConditionalOnXxx | 第 1 次 |