# `@Configuration` 注解详解
08、底层注解-@Configuration详解
`@Configuration` 是 Spring 框架中用于定义配置类的核心注解,它允许开发者以 Java 代码的形式替代传统的 XML 配置,声明和管理 Bean。
## 一、基本作用
### 1. 标识配置类
使用 `@Configuration` 注解标记的类被视为 Spring 的配置类,Spring 容器在启动时会自动扫描并处理这些类。
### 2. 定义 Bean
在配置类中,通过 `@Bean` 注解的方法可以定义 Bean。这些方法返回的对象将被注册到 Spring 容器中,供其他组件依赖注入。
```java
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
```
### 3. 依赖注入
配置类中的 `@Bean` 方法可以接受其他 Bean 作为参数,实现依赖关系的自动装配。
```java
@Configuration
public class AppConfig {
@Bean
public MyService myService(MyRepository repository) {
return new MyServiceImpl(repository);
}
@Bean
public MyRepository myRepository() {
return new MyRepositoryImpl();
}
}
```
## 二、核心特性
### 1. 单例模式
默认情况下,`@Configuration` 类中的 `@Bean` 方法返回的 Bean 是单例的,即在整个应用程序生命周期中只创建一个实例。
### 2. 代理机制
#### Full 模式(默认)
- **特性**:`proxyBeanMethods = true`,Spring 使用 CGLIB 为配置类生成代理对象。
- **作用**:确保每次调用 `@Bean` 方法都返回容器中的同一个单例 Bean,避免重复创建。
- **适用场景**:配置类之间存在复杂的依赖关系。
#### Lite 模式
- **特性**:`proxyBeanMethods = false`,不生成代理对象。
- **作用**:每次调用 `@Bean` 方法都会创建新的实例,提升性能。
- **适用场景**:配置类之间没有依赖关系,或希望减少启动时间。
```java
@Configuration(proxyBeanMethods = false) // 启用 Lite 模式
public class AppConfig {
// ...
}
```
### 3. 条件化配置
结合 `@Conditional` 注解,根据特定条件决定是否创建 Bean。
```java
@Configuration
public class ConditionalConfig {
@Bean
@ConditionalOnProperty(name = "my.property", havingValue = "true")
public MyBean myBean() {
return new MyBean();
}
}
```
### 4. 模块化配置
使用 `@Import` 注解导入其他配置类,实现配置的模块化和复用。
```java
@Configuration
@Import(AnotherConfig.class)
public class AppConfig {
// ...
}
```
## 三、使用注意事项
### 1. 避免循环依赖
在配置类中尽量避免循环依赖,否则可能导致 Spring 容器启动失败。
### 2. 配置类的可见性
配置类应声明为非 `final`,且不能是局部类,以便 Spring 生成代理类。
### 3. 慎用 `@Bean` 方法调用
在 Full 模式下,不要在 `@Bean` 方法内部直接调用其他 `@Bean` 方法,应使用依赖注入获取 Bean,避免创建多余的实例。
## 四、示例
### 1. 基本配置
```java
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
@Bean
public MyRepository myRepository() {
return new MyRepositoryImpl();
}
}
```
### 2. 条件化配置
```java
@Configuration
public class DatabaseConfig {
@Bean
@ConditionalOnProperty(name = "db.type", havingValue = "mysql")
public DataSource mysqlDataSource() {
// 创建 MySQL 数据源
return new MysqlDataSource();
}
@Bean
@ConditionalOnProperty(name = "db.type", havingValue = "postgresql")
public DataSource postgresqlDataSource() {
// 创建 PostgreSQL 数据源
return new PostgresqlDataSource();
}
}
```
---
通过合理使用 `@Configuration` 注解,可以简化 Spring 应用的配置管理,提高代码的可读性和可维护性,实现更加灵活和高效的依赖注入。