Spring bean 注册多种方式

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
  1. @Import 支持 3 种类型:Configuration类 / ImportSelector / ImportBeanDefinitionRegistrar
  2. BeanDefinition 只是Bean 的元数据描述 ,此时对象还没实例化;registerSingleton是直接注册成品实例。
  3. 优先级:BeanDefinitionRegistryPostProcessor 执行时机早于普通 BeanFactoryPostProcessor。
相关推荐
铁皮饭盒1 小时前
还是网页端, 46mb模型, 抠图功能升级了, 抠任意主体, 还是不要显卡, 不要python, 满意吗?
前端·javascript·后端
小林coding1 小时前
Flash模型又添一员大将:实测MiniMax M3.1
后端
鬼手点金1 小时前
opencode-性能优化建议
java·人工智能·git·自动化·nanogpt
聪明蛋子哟1 小时前
Python与Java双栈实战:手撸一个支持RAG与Tool Calling的高性能Agent框架
java·开发语言·python
xuxigifxfh1 小时前
HJ4 字符串分隔
java·开发语言·华为机考
写后端的胖头鱼1 小时前
Java 反射详解 + 场景示例
java·反射
零基础1232 小时前
PDF 处理工具全攻略:pdf24、PDFgear、Adobe Acrobat DC 与 Stirling-PDF 深度对比
java·开发语言·pdf
颜进强2 小时前
25 · NestJs DurableProviders 持久化 Provider:把 ContextId 当缓存键
前端·后端·ai编程