外观
介绍一下 @Configuration 注解
⭐ 题目日期:
小红书 - 2024/11/11
📝 题解:
在 Spring 框架中,@Configuration
注解用于标记一个类为 配置类,替代传统的 XML 配置文件,通过 Java 代码定义和组装 Bean。以下是其核心作用、使用方式及原理详解:
1. 核心作用
- 定义 Bean:通过
@Bean
注解在配置类中显式声明 Spring Bean。 - 替代 XML:以类型安全的方式替代 XML 配置,实现依赖注入和组件管理。
- 模块化配置:支持多配置类组合(通过
@Import
或组件扫描)。 - 条件化装配:结合
@Conditional
注解实现按条件加载 Bean。
2. 基础用法示例
@Configuration
public class AppConfig {
// 声明一个 Bean,方法名默认为 Bean 名称
@Bean
public DataSource dataSource() {
return new HikariDataSource();
}
// 依赖注入:通过方法参数引用其他 Bean
@Bean
public UserService userService(DataSource dataSource) {
return new UserServiceImpl(dataSource);
}
}
3. 工作原理
- CGLIB 代理:Spring 在启动时会对
@Configuration
类进行字节码增强(通过 CGLIB 代理),确保所有@Bean
方法返回的是 单例对象。 - 拦截调用:代理类会拦截
@Bean
方法的调用,确保多次调用同一方法时返回同一个 Bean 实例。 - 解决内部依赖:在配置类内部调用
@Bean
方法时,代理会确保返回已创建的 Bean,而非每次都创建新实例。
4. 与 @Component 的区别
示例对比:
@Configuration
public class ConfigA {
@Bean
public A a() {
return new A(b()); // 代理介入,返回单例 B
}
@Bean
public B b() {
return new B();
}
}
@Component
public class ComponentA {
public A a() {
return new A(b()); // 直接调用,每次创建新 B
}
public B b() {
return new B();
}
}
5. 高级特性
(1) 组合配置(@Import)
@Configuration
@Import({DatabaseConfig.class, SecurityConfig.class})
public class AppConfig {
// 导入其他配置类
}
(2) 条件化装配(@Conditional)
@Bean
@ConditionalOnProperty(name = "cache.enabled", havingValue = "true")
public CacheManager cacheManager() {
return new RedisCacheManager();
}
(3) 环境配置(@Profile)
@Configuration
@Profile("production")
public class ProdConfig {
@Bean
public DataSource prodDataSource() {
// 生产环境数据源配置
}
}
(4) 外部化配置(@PropertySource)
@Configuration
@PropertySource("classpath:app.properties")
public class PropertyConfig {
@Value("${jdbc.url}")
private String jdbcUrl;
}
6. 使用场景
- 显式定义 Bean:当需要精确控制 Bean 的创建逻辑(如第三方库集成)。
- 多环境配置:通过
@Profile
分离开发、测试、生产环境的配置。 - 模块化架构:大型项目中按功能模块拆分多个配置类。
- 条件化启动:根据系统属性或类路径条件动态装配组件。
7. 注意事项
- 避免直接调用同类中的 @Bean 方法:在非
@Configuration
类中,直接调用@Bean
方法会创建新实例,应通过参数依赖注入。 - 代理限制:
@Configuration
类不能是final
类,且@Bean
方法不能是private
或final
。 - 性能开销:CGLIB 代理会带来轻微性能损耗,但对大多数应用无显著影响。
总结
@Configuration
是 Spring 实现 Java 配置 的核心注解,通过类型安全的代码替代 XML,提供了灵活、模块化的 Bean 管理方式。结合 @Bean
、@Import
和条件化注解,能够高效应对复杂应用的配置需求,是现代 Spring 应用开发的首选配置方式。