Spring bean 注册多种方式
Spring 提供了多种注册方式,主要有以下几种
1. @Component 及其衍生注解
直接注解业务 Class,类被包扫描后自动注册为 Bean
java
@Component
public class EmployeeService {}
衍生注解(语义化,底层都是 @Component)
java
// 业务层
@Service
// 数据访问层
@Repository
// MVC 控制器
@Controller
// RESTFul 方式的 @Controller
@RestController
// 配置类
@Configuration
SpringBoot 通过 @SpringBootApplication 开启包扫描,扫描当前主类所在包及其所有子包。
2. @Bean
在@Configuration配置类中定义方法,返回对象,注册为 Bean
java
@Configuration
public class ProjConfig {
@Bean
public AddressService addressService() {
return new AddressService();
}
}
适用场景:
- 第三方库类(无法修改源码加 @Component)
- 需要显式调用构造 / 工厂方法,自定义对象创建逻辑
- 复杂对象装配、多参数构建
3. @Import
导入配置类 configuration class 或者组件 component
java
@Configuration
public class ShareProjConfig {}
// 方式1:放在启动类
@Import(ShareProjConfig.class)
@SpringBootApplication
public class MainApplication {}
// 方式2:放在其他配置类
@Import(ShareProjConfig.class)
@Configuration
public class ProjConfig {}
4. @ImportResource
兼容老项目,加载 XML 配置文件,从 xml 中注册 Bean
xml
<bean id="addressService" class="pr.iceworld.fernando.AddressService">
...
<bean id=...>
java
@Configuration
@ImportResource("classpath:beans.xml")
public class ProjConfig{
}
5. ImportBeanDefinitionRegistrar(动态注册 BeanDefinition)
注意:BeanDefinitionRegistry 是注册器对象 ,不是接口名!
实现
ImportBeanDefinitionRegistrar,动态注册 BeanDefinition,框架级动态注册
java
public class CustomConfig implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
BeanDefinition bd = BeanDefinitionBuilder
.genericBeanDefinition(AddressService.class)
.getBeanDefinition();
registry.registerBeanDefinition("addressService", bd);
}
}
特点:在 Bean 实例化前注册 BeanDefinition,多用于框架扩展。
6. BeanDefinitionRegistryPostProcessor
Bean 工厂后置处理器,在所有 BeanDefinition 加载完成、Bean 实例化之前新增 / 修改 Bean 定义
java
@Component
public class CustomBeanRegistrar implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
BeanDefinition bd = BeanDefinitionBuilder
.rootBeanDefinition(AddressService.class)
.getBeanDefinition();
registry.registerBeanDefinition("addressService", bd);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {}
}
适用:底层架构、中间件框架开发。
7. registerSingleton 直接注册单例对象
向 BeanFactory 注册已经 new 好的实例对象
⚠️重点:该对象不会执行 Spring 完整 Bean 生命周期(不会执行 InitializingBean、Aware 回调等)
java
@Configuration
public class RuntimeProjConfig {
@Bean
public BeanFactoryPostProcessor registrar() {
return beanFactory -> {
beanFactory.registerSingleton("addressService", new AddressService());
};
}
}
8. @ConfigurationPropertiesScan
扫描带有@ConfigurationProperties的配置绑定类,读取配置文件映射到 Java 对象。
作用:注册配置属性类 Bean,绑定 properties/yaml 配置,不是通用业务 Bean 注册
application.properties
properties
proj.name=xxx
java
@ConfigurationProperties(prefix = "proj")
public class ProjProperties {
private String name;
// getter / setter
}
@ConfigurationPropertiesScan
@SpringBootApplication
public class MainApplication {}
9. @EnableXXX 系列注解(间接注册 Bean)
底层依靠
@Import导入内部配置类,由配置类注册对应的 Bean,属于间接方式
java
@EnableScheduling
@EnableCaching
@EnableAsync
@EnableTransactionManagement
java
@EnableAsync
@SpringBootApplication
public class MainApplication {}
总结
| 场景 | 推荐方式 |
|---|---|
| 自己项目内业务类,可直接加注解 | @Component / @Service / @Repository / @Controller |
| 第三方类、需要自定义构造创建对象 | @Bean |
| 导入外部配置类、组件 | @Import |
| 老项目兼容XML Bean定义 | @ImportResource |
| 配置文件绑定属性类 | @ConfigurationPropertiesScan |
| 框架动态注册BeanDefinition | ImportBeanDefinitionRegistrar / BeanDefinitionRegistryPostProcessor |
| 直接注入已实例化对象 | beanFactory.registerSingleton |
@Import支持 3 种类型:Configuration类/ImportSelector/ImportBeanDefinitionRegistrar- BeanDefinition 只是Bean 的元数据描述 ,此时对象还没实例化;
registerSingleton是直接注册成品实例。 - 优先级:BeanDefinitionRegistryPostProcessor 执行时机早于普通 BeanFactoryPostProcessor。