优先用@Component(如@Service)管理自定义业务类,因其支持自动扫描和语义化标注;必须用@Bean管理第三方类、复杂初始化或条件化Bean,因其提供显式编程控制和灵活定制能力。

选 @Component 还是 @Bean,关键看“谁控制创建”和“能不能改源码”。自己写的业务类,优先用 @Component(或它的语义化变体);第三方类、需要定制初始化逻辑、或依赖动态条件的场景,必须用 @Bean。
什么时候用 @Component
适用于你完全掌控源码、结构清晰、可被 Spring 自动扫描的自定义类:
- 类本身可以加注解,比如
@Service、@Repository、@Controller(它们都是@Component的派生) - 项目已启用组件扫描(如主类上有
@SpringBootApplication,它自带@ComponentScan) - 实例化逻辑简单:默认构造、或依赖能通过
@Autowired自动注入 - 不需要在创建时读配置、做判断、调外部 API 或组合多个对象
什么时候用 @Bean
适用于无法修改类源码,或创建过程需要开发者显式干预的场景:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 第三方库类(如
HikariDataSource、RestTemplate、ObjectMapper),不能加@Component - 同一个接口有多个实现,需根据环境/配置/参数返回不同实例(例如按 profile 创建不同的
PaymentService) - 创建过程涉及复杂逻辑:读取 properties/yml、校验参数、设置连接池属性、包装代理、初始化回调等
- Bean 之间有明确依赖顺序,且需在方法参数中直接引用其他 Bean(Spring 自动注入)
@Component 和 @Bean 能混用吗
可以,而且常见。但要注意职责分离:
立即学习“Java免费学习笔记(深入)”;
-
@Configuration类里用@Bean定义基础设施 Bean(数据源、客户端、工具类) - 业务逻辑类(
UserService、OrderProcessor)用@Service(即@Component)标记,由 Spring 扫描管理 - 如果在
@Bean方法中 new 出一个@Component类,就绕过了 Spring 的生命周期管理(比如@PostConstruct不会执行),应避免 - 不推荐在普通
@Component类里写@Bean方法——虽技术可行,但语义混乱,违背配置与业务分离原则
命名与作用域的小细节
两个注解默认都注册为单例(singleton),但名字来源和扩展方式不同:
-
@Component默认 Bean 名是类名首字母小写(如UserService→userService),可用@Component("myUserSvc")显式指定 -
@Bean默认 Bean 名是方法名(如dataSource()→dataSource),也可用@Bean("mainDs")改名 - 作用域都支持
@Scope,但@Bean更容易结合@ConditionalOnProperty等条件注解做开关控制

















