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。
相关推荐
yz_aiks8 小时前
Spring AI 2.1 ChatMemory 已过时用什么替代:迁移到 Session Memory 实战(JDBC 存储与会话压缩)
java·spring boot·大模型·ai agent·spring ai
金銀銅鐵9 小时前
[Java] 用 GUI 展示 EnumMap 增删键值对时的内部变化
java·后端·ai编程
学长毕设9 小时前
基于SpringBoot的上门洗车服务系统设计与实现
java·spring boot·后端
jason成都9 小时前
RTKLIB-Java 多基线联合RTK:FIX率从0%到91.5%的三层根因修复
java·gnss·rtklib·rtklib_java
鱼宵9 小时前
Stream 终端操作一次讲透:collect、count、reduce 怎么选
java·stream·终端操作
白山编程大哥9 小时前
Java 后端如何优雅地把 List 集合返回给前端
java·前端·list
Linux运维技术栈9 小时前
CVE-2026-91403 高危漏洞修复:Rocky Linux 9 多版本 JDK 环境清理实操
java·linux·运维
On The Road :10 小时前
Java 多线程详解:从入门到线程安全
java·python·安全
Shaoshing10 小时前
LeetCode100 49. 字母异位词分组
java·算法
划破黑暗的第一缕曙光11 小时前
[C++]:5.STL:string(2)
java·c++·redis