Spring Boot 自动配置:引入依赖后,Bean 是怎么创建的?
开篇
依赖已经加上,预期的 Bean 却没有出现;打开一个配置开关,又开始提示缺少依赖。自动配置不是“引入 jar 就全部创建”。下面沿着入口、条件和工厂方法,看看一组缓存 Bean 到底怎样加入容器。
环境:JDK 21、Spring Boot 3、Spring Framework 6、Caffeine 3。以下配置类和缓存包装组件均为应用自有实现,不是 Boot 原生缓存配置。
坑点
坑点一:只看见 @Bean,没看到配置类的开关与依赖
这组 Bean 所在的配置类有明确的属性条件,工厂方法还要从容器取得其他组件:
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = {"cache.caffeine.enabled"}, havingValue = "true")
@EnableConfigurationProperties({CaffeineProperties.class})
public class CaffineConfiguration {
@Bean
public CaffeineCallLogger caffeineCallLogger() {
return new CaffeineCallLogger();
}
@Bean
public CaffeineHelper caffeineHelper(CaffeineCallLogger caffeineCallLogger, InternalServiceClient internalServiceClient) {
return new CaffeineHelper(caffeineCallLogger, internalServiceClient);
}
@Bean
public CaffeineCacheManager caffeineCacheManager(CaffeineHelper caffeineHelper) {
return new CaffeineCacheManager(caffeineHelper);
}
@Bean
public CaffeineApi caffeineApi() {
return new CaffeineApi();
}
}
只有 cache.caffeine.enabled 满足 true,配置才参与创建。未配置或为 false 时,不会仅因文件里写了 @Bean 就自动生效。
正确写法
避坑一:按“入口 → 条件 → 依赖 → 初始化”逐步检查
依赖包的 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 需要列出自动配置入口的完整类名。入口再通过 @Import 引入刚才的 CaffineConfiguration,不必让业务应用随意扩大组件扫描范围。Spring Boot 自动配置说明
下面是自动配置入口上的真实注解组:
@AutoConfiguration
@Import({
RpcConfiguration.class,
CaffineConfiguration.class,
RedisConfiguration.class,
L2CacheConfiguration.class,
SpringScheduledJobConfiguration.class
})
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
@EnableConfigurationProperties({AspectLogProperties.class, ConcurrentProperties.class})
这里的 CaffineConfiguration 名称沿用类名。它被发现与它最终创建成功,是两件事:入口能导入配置,但属性条件、工厂方法依赖和初始化检查仍然会生效。
配置开关打开之后,还需要什么
最小属性示例为:
cache:
caffeine:
enabled: true
instance-list:
- name: local
spec: maximumSize=1000
这不是完整应用配置,只描述该缓存区域。创建 CaffeineHelper 还需要 InternalServiceClient;CaffeineCallLogger 的继承字段需要日志配置;缓存管理器初始化时要求 instanceList 非空。缺少这些条件,不能认为 enabled=true 就一定启动成功。
本地容器验证分别检查了两种关闭状态:没有属性、属性为 false,均未创建这组 Bean。打开开关的验证只检查真实配置条件匹配,不替代完整应用启动和 RPC 依赖检查。
为什么 @Bean 方法通过参数取得依赖
下面这行签名已经表达了依赖关系:
public CaffeineCacheManager caffeineCacheManager(CaffeineHelper caffeineHelper)
参数由容器提供。配置类使用 proxyBeanMethods=false,不依赖同一个配置对象上 @Bean 方法之间的代理调用。
如果改成在方法体里直接调用另一个工厂方法,需要重新检查是否绕过了容器管理并创建新对象。通过参数注入依赖,也更容易看出缺少哪个 Bean。
自定义同类型 Bean,会自动替换默认实现吗
不会仅因为它叫“自动配置”就获得退让能力。这份配置没有 @ConditionalOnMissingBean,所以业务方另加一个同类型 Bean,不代表这里的工厂方法会自动跳过。
不同名称可能同时存在,随后按类型注入可能产生歧义;相同名称还会受 Bean 覆盖配置等规则影响。想替换某个组件,必须先看条件和注入点,不能凭约定猜它会让位。
总结
先找自动配置入口,再看条件是否成立,最后检查工厂方法依赖和初始化约束。Bean 没出现与 Bean 创建失败是两类问题,自定义实现能否替换也要看真实条件。
如果这篇文章对您有用,欢迎关注。后续会继续拆解 Java 后端的实用代码,讲清写法、原理和使用时要注意的细节。
本文深入解析Spring Boot自动配置中Bean的创建机制,涵盖自动配置入口(AutoConfiguration.imports)、条件注解(如@ConditionalOnProperty)控制开关、工厂方法依赖注入、初始化约束检查等关键环节。重点说明@Bean方法参数注入依赖的必要性、自定义Bean是否覆盖默认实现的判定逻辑,以及常见坑点如忽略属性条件或缺失依赖导致Bean未注册的问题。

4587

被折叠的 条评论
为什么被折叠?



