跳到正文
Elaine Blog
返回

配置类、组件扫描与条件装配

Spring 生态与源码

Spring 配置的最终产物都是 BeanDefinition。@Component@Bean@Import 和自动配置只是不同的定义来源,理解这一点就能统一排查“为什么这个 Bean 出现或缺失”。

Table of contents

Open Table of contents

从配置类开始实验

LabConfiguration下载声明一个 Clock

@Configuration(proxyBeanMethods = false)
class LabConfiguration {
    @Bean Clock clock() { return Clock.systemDefaultZone(); }
}

proxyBeanMethods=false 表示不需要用 CGLIB 拦截配置类内部方法调用,适合各 @Bean 方法彼此不直接调用的配置,启动成本和语义都更清楚。

配置解析主线

ConfigurationClassPostProcessor 是 BeanFactoryPostProcessor。它在普通单例创建前解析:

  1. 配置类候选;
  2. @ComponentScan 找到的组件;
  3. @Import 导入类、Selector 和 Registrar;
  4. @Bean 工厂方法;
  5. @Conditional 是否满足;
  6. 将结果注册为 BeanDefinition。

组件扫描以启动类所在包为默认根。把启动类放得太深会漏扫,把根放得太高又可能纳入测试或其他应用配置。大型系统更适合显式模块配置和 @Import

条件装配必须可解释

条件可以检查类路径、Bean、属性或 Web 应用类型。自动配置通常使用“类存在、用户尚未提供同类 Bean”作为后备方案。

条件只在注册阶段决定定义是否出现,不应拿它实现运行时每请求业务分支。排查时查看 Condition Evaluation Report,确认哪个条件匹配或不匹配,而不是盲目增加扫描路径。

配置边界就是模块边界

一个模块对外提供少量配置入口,内部组件保持包私有;调用方通过 @Import 或启动器显式启用。这样测试可以只加载所需模块,也能避免同名 Bean 和意外扫描。

下一步

阅读Spring 扩展点实战,按“修改配方、注册配方、加工对象、接收事件”选择正确接口。


分享这篇文章:

上一篇
三级缓存能解决什么循环依赖
下一篇
Spring 扩展点实战:Registrar、Factory、PostProcessor 与 Listener