spring 使用 @configuration 配置类替代 xml,核心是用 @bean 方法定义 bean 并由 @configuration 标识配置源头,实现可编译、可调试、有类型检查的配置;配合 @componentscan 替代组件扫描,@conditional 系列注解支持条件化配置,并需注意 full 模式(默认 cglib 代理保障单例)与 lite 模式的区别。

Spring 使用 @Configuration 配置类替代 XML 配置,核心是把原来写在 beans.xml 里的 <bean></bean> 标签,换成 Java 类中带 @Bean 注解的方法,再用 @Configuration 标记这个类为“配置源头”。它不是简单语法替换,而是让配置变成可编译、可调试、有类型检查的代码。
配置类怎么写:@Configuration + @Bean
一个标准配置类长这样:
- 类上加
@Configuration,告诉 Spring:“这是我定义 Bean 的地方”; - 每个 Bean 对应一个方法,方法上加
@Bean,返回值就是注册进容器的对象; - Bean 名称默认是方法名,也可用
@Bean("xxx")显式指定; - 方法参数可以自动注入其他 Bean(Spring 会按类型匹配并解析依赖)。
例如,原来 XML 中:
现在写成:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
@Configuration<br>public class DataSourceConfig {<br> @Bean<br> public DataSource dataSource() {<br> DriverManagerDataSource ds = new DriverManagerDataSource();<br> ds.setUrl("jdbc:h2:mem:test");<br> return ds;<br> }<br>}
替代组件扫描:@ComponentScan
XML 中的 <component-scan base-package="com.example"></component-scan>,对应 Java 配置里的 @ComponentScan:
- 直接加在
@Configuration类上,比如@ComponentScan("com.example.service"); - 不填参数时,默认扫描启动类所在包及其子包(Spring Boot 自动生效);
- 支持过滤规则,如只扫
@Service类:@ComponentScan(includeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Service.class))。
替代条件化配置:@Conditional 系列
XML 难以实现“开发环境用 H2,生产环境用 MySQL”,而 Java 配置天然支持逻辑判断:
-
@Profile("dev"):仅在 dev profile 下生效; -
@ConditionalOnMissingBean(DataSource.class):容器里没 DataSource 才注册这个 Bean; -
@ConditionalOnProperty(name = "cache.enabled", havingValue = "true"):根据配置项开关决定是否加载缓存配置。
这些注解可直接加在 @Bean 方法或整个 @Configuration 类上,实现灵活的环境适配。
注意代理行为:Full 模式 vs Lite 模式
@Configuration 类默认启用 CGLIB 代理(Full 模式),这是关键细节:
- 同一个配置类内多次调用
@Bean方法(比如 A 方法里 new 了 B 方法返回的对象),Spring 保证返回的是同一个单例实例; - 若误用
@Component替代@Configuration,或关闭代理(@Configuration(proxyBeanMethods = false)),就会变成普通方法调用——每次执行都 new 一个新对象,破坏单例语义; - 只有明确不需要 Bean 间调用、且追求轻量时,才考虑 Lite 模式。










