Spring中生成Bean的方式总结-笔记
1. 概略版
Spring生成Bean方式有如下几种,可根据需求选择合适的方式,通常优先使用注解驱动的声明式配置(如@Component
、@Bean
),复杂场景结合条件或作用域控制。
方式 | 特点 | 适用场景 |
---|---|---|
@Component + 组件扫描 | 简单直观,依赖扫描机制 | 通用Bean的快速注册 |
@Configuration + @Bean | 显式定义,灵活控制初始化逻辑 | 需要复杂配置或依赖注入时 |
@ConfigurationProperties + @EnableConfigurationProperties | 配置属性绑定 | 从配置文件读取属性并映射到Bean |
@Import | 模块化配置管理 | 将配置拆分为多个类 |
@ImportResource | XML配置兼容 | 需要兼容旧版XML配置 |
2. 详情版
1. 使用 @Component
及组件扫描 (@ComponentScan
)
作用:
- 通过注解标记类为Bean,结合组件扫描自动注册Bean。
适用场景:
- 通用Bean的注册,如Service、Repository等。
用法:
- 在类上添加
@Component
或其衍生注解(@Service
,@Repository
,@Controller,@RestController
)。 - 在配置类上添加
@ComponentScan
指定扫描包路径(或使用Spring Boot的自动扫描特性)。
示例:
// 定义Bean类
@Component
public class UserService {public void sayHello() {System.out.println("Hello from UserService");}
}// 配置类(可省略,Spring Boot默认扫描主类所在包及其子包)
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
}
2. 通过 @Configuration
和 @Bean
方法
作用:
- 通过Java配置类显式声明Bean。
适用场景:
- 需要复杂初始化逻辑或依赖其他Bean时。
用法:
- 在配置类上添加
@Configuration
。 - 在配置类中通过
@Bean
注解方法定义Bean。
示例:
@Configuration
public class AppConfig {@Beanpublic MyService myService() {MyService service = new MyService();service.setParam("configured");return service;}
}// 使用Bean
@Service
public class AnotherService {@Autowiredprivate MyService myService; // 自动注入由@Bean生成的Bean
}
3. 使用 @ConfigurationProperties
+ @EnableConfigurationProperties
作用:
- 将配置属性绑定到Java类,并自动注册为Bean。
适用场景:
- 从配置文件(如
application.properties
)中读取属性并映射到Bean。
用法:
- 在类上添加
@ConfigurationProperties
指定属性前缀。 - 在配置类上通过
@EnableConfigurationProperties
注册该类。
示例:
//application.properties文件的配置内容
test.app.name=bigbear-demo1
test.app.timeout=1000// 定义配置类
@Data
@ConfigurationProperties(prefix = "test.app")
public class AppProperties {private String name;private int timeout;
}// 在配置类中启用
@Configuration
@EnableConfigurationProperties(AppProperties.class)
public class AppConfig {
}// 使用Bean
@Service
public class MyService {@Autowiredprivate AppProperties appProps; // 可获取配置属性值
}
4. 使用 @Import
注入其他配置类
作用:
- 导入其他配置类,批量注入其定义的Bean。
适用场景:
- 模块化配置,将不同配置拆分到多个类中。
用法:
- 在主配置类上添加
@Import
,指定需导入的配置类。
示例:
// 第一个配置类
@Configuration
public class DBConfig {@Beanpublic DataSource dataSource() { ... }
}// 第二个配置类
@Configuration
public class ServiceConfig {@Beanpublic UserService userService() { ... }
}// 主配置类
@Configuration
@Import({DBConfig.class, ServiceConfig.class})
public class AppConfig {
}
5. 通过 @ImportResource
加载XML配置
作用:
- 将XML配置中的Bean导入到Spring容器中。
适用场景:
- 兼容旧版XML配置或混合使用XML/Java配置。
用法:
- 在配置类上添加
@ImportResource
,指定XML文件路径。
示例:
@Configuration
@ImportResource("classpath:applicationContext.xml")
public class AppConfig {// XML中定义的Bean会被自动注册
}
3. 影响bean生成的方式
1. 使用 @Conditional
条件化生成Bean
作用:
- 根据条件动态决定是否生成Bean。
适用场景:
- 根据环境、依赖等条件选择性注册Bean。
用法:
- 在Bean方法或类上添加
@Conditional
及其衍生注解(如@ConditionalOnClass
,@ConditionalOnProperty
)。
示例:
@Configuration
@ConditionalOnBean(AppManager.class)
public class AppConfig {@Bean@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")public FeatureService featureService() {return new FeatureService();}@Bean@ConditionalOnMissingBean(EessageClient.class)public FeatureService messageClient() {return new EessageClient();}}
2. 使用 @Scope
定制Bean作用域
作用:
- 修改Bean的作用域(如单例、原型等)。
适用场景:
- 需要控制Bean的生命周期和线程安全性。
用法:
- 在Bean方法或类上添加
@Scope
。
示例:
@Configuration
public class AppConfig {@Bean@Scope("prototype") // 每次注入生成新实例public MyPrototypeBean myBean() {return new MyPrototypeBean();}
}
3. 使用 @Lazy
延迟初始化Bean
作用:
- 延迟Bean的初始化直到第一次使用时。
适用场景:
- 避免ApplicationContext启动时加载不必要的Bean。
用法:
- 在Bean方法或类上添加
@Lazy
。
示例:
@Configuration
public class AppConfig {@Bean@Lazypublic ExpensiveToInitializeBean expensiveBean() {return new ExpensiveToInitializeBean();}
}