继承关系
@Configuration
确实可以视为@Component
的派生注解。从源码层面来看,@Configuration
本身通过元注解方式标记了@Component
,这意味着所有被@Configuration
注解的类本质上也会被Spring识别为组件(Component)。这种设计使得@Configuration
类既能享受组件扫描的特性,又具备配置类的特殊能力。
功能差异
尽管存在继承关系,但两者的核心功能截然不同。@Component
是通用组件标识,用于将普通类纳入Spring容器管理;而@Configuration
专用于配置类定义,其内部通过@Bean
方法显式声明Bean,并通过CGLIB动态代理确保方法间调用返回同一实例,从而实现单例模式。这种代理机制是@Component
类所不具备的。
代理行为差异
@Configuration
类会经过Spring的增强处理,生成CGLIB代理类,使得@Bean
方法在多次调用时返回容器中的现有实例。而使用@Component
注解的配置类不会触发代理,直接执行原始方法逻辑,导致每次调用@Bean
方法都会生成新实例。这种行为差异直接影响Bean的作用域管理,是两者最显著的技术区别。
使用场景区分
实际开发中,@Component
适用于常规业务组件(如Service、Repository),而@Configuration
专门用于集中式配置场景。当需要定义Bean之间的依赖关系或复杂初始化逻辑时,必须使用@Configuration
以保证Bean的正确实例化顺序和单例特性,这是单纯使用@Component
无法实现的。
代理机制与实例化逻辑
@Configuration 的代理行为
配置类会被 Spring 生成代理子类(如 MyConfig$$EnhancerBySpringCGLIB
),拦截 @Bean
方法调用,确保多次调用返回同一对象
限制:配置类不能是 final
、不能是 private
方法,且需以类形式定义(非工厂方法返回的实例)
@Component 的无代理模式
@Bean
方法直接执行,每次调用生成新对象。若需单例,需依赖 Spring 容器(如通过参数注入)
适用场景
使用 @Configuration 的场景
需要集中管理 Bean 的依赖关系和初始化逻辑。
确保 @Bean
方法间的调用复用同一实例(如数据库配置、线程池配置)
使用 @Component 的场景
简单定义 Bean,无需复杂依赖。
避免代理(如某些 AOP 场景需原始类)或类无法满足 @Configuration
的限制