当前位置: 首页 > news >正文

@Configuration 与 @Component 的区别

  

目录

1、基本概念

1.1、@Component

1.2、@Configuration

2、代理类

2.1、保证Bean的单例性

2.2、提供完整的Bean生命周期

2.3、实现配置类的特殊行为

2.4、容器一致性保障

3、代理流程

3.1 代理流程分类

1、Full 模式(默认):

2、Lite 模式:

3.2、启动流程

3.3、底层机制

1、代理创建时机

2、代理类的工作方式

3.4、如何验证代理行为

4、性能考量

5、最佳实践建议


前言

        在Spring框架中,有许多常用的注解来定义类,以下常用的是@configuration和@component。

         Web 应用程序采用了经典的三层分层结构的话,在持久层、业务层和控制层分别采用 @Repository、@Service 和 @Controller 对分层中的类进行注释,而 @Component 就是对那些比较中立的类进行注释。

如下:

         <context:component-scan base-package=”com.*”>上面的这个是引入Component组件的例子,其中base-package表示为需要扫描的所有子包。

        从Spring3.0,@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。

以下就是两者的区别:


1、基本概念

1.1、@Component

@Component 源码片段:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {String value() default "";
}
  •         Spring 核心注解,最基础的组件标记注解。

  • 作用:标识一个类作为 Spring 组件(Bean),会被组件扫描自动检测并注册到容器

  • 衍生注解

    • @Service(服务层)

    • @Repository(持久层)

    • @Controller(控制层)

  • 典型场景

    • 业务逻辑组件

    • 工具类组件

    • 非配置型的通用组件

1.2、@Configuration

@Configuration 源码片段

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {@AliasFor(annotation = Component.class)String value() default "";boolean proxyBeanMethods() default true;
}
  •         Spring 专门用于配置的增强型注解。

  • 本质:是一种特殊的 @Component(包含 @Component 元注解)

  • 核心能力

    • 定义 Bean 的装配规则

    • 支持跨 Bean 引用

    • 集成条件化配置(如 @Conditional

  • 典型场景

    • 应用主配置类

    • 数据库/缓存等基础设施配置

    • 第三方库集成配置

通过对比可以发现:

  • @Configuration 是 @Component 的派生注解(带有 @Component 元注解)。

  • @Configuration 特有的 proxyBeanMethods 属性控制代理行为。


2、代理类

Spring为@Configuration类生成CGLIB代理主要出于以下几个关键原因:

2.1、保证Bean的单例性

@Configuration类中的@Bean方法相互调用时:

@Configuration
public class AppConfig {@Beanpublic A a() {return new A(b()); // 调用b()方法}@Bean public B b() {return new B();}
}

无代理情况(如使用@Component):

  • 每次调用b()都会创建新的B实例

  • A和B无法保持单例性

有代理情况

  • 代理会拦截方法调用

  • 确保相同的b()总是返回同一个实例

  • 维护Spring容器的单例契约

2.2、提供完整的Bean生命周期

代理类能够:

  • 处理@PostConstruct/@PreDestroy等生命周期回调

  • 正确处理BeanFactoryAware等接口

  • 管理Bean的依赖关系

2.3、实现配置类的特殊行为

代理使得@Configuration 特有功能:

  • 支持 @Bean 方法间的调用

  • 完美配合 @Import/@ImportResource

  • 原生支持 @Profile 等条件化配置

  • 与 @Enable* 系列注解深度集成

2.4、容器一致性保障

如下图所示:

代码示例:

1、原始类:

@Configuration
public class DataConfig {@Beanpublic DataSource dataSource() {return new HikariDataSource(config());}@Beanpublic HikariConfig config() {return new HikariConfig();}
}

2、代理类伪代码:

public class DataConfig$$EnhancerBySpringCGLIB extends DataConfig {private BeanFactory beanFactory;@Overridepublic DataSource dataSource() {// 1. 检查Bean是否已存在if (beanFactory.containsBean("dataSource")) {return (DataSource) beanFactory.getBean("dataSource");}// 2. 通过父类方法创建新实例return super.dataSource(); // 会触发config()的代理逻辑}@Overridepublic HikariConfig config() {// 同样的单例保证逻辑if (beanFactory.containsBean("config")) {return (HikariConfig) beanFactory.getBean("config");}return super.config();}
}


3、代理流程

3.1 代理流程分类

1、Full 模式(默认):

需要完整代理。

2、Lite 模式

轻量级配置。

    使用 @Component + @Bean或 @Configuration(proxyBeanMethods = false)

    3.2、启动流程

    1. ConfigurationClassPostProcessor 开始处理

    2. 调用 ConfigurationClassUtils.checkConfigurationClassCandidate()

    3. 识别真正的 @Configuration 类(非lite模式)

    CGLIB代理生成过程

    // ConfigurationClassEnhancer 内部实现
    public Enhancer newEnhancer(Class<?> configSuperClass, ClassLoader classLoader) {Enhancer enhancer = new Enhancer();enhancer.setSuperclass(configSuperClass);enhancer.setInterfaces(new Class<?>[] {EnhancedConfiguration.class});enhancer.setUseFactory(false);enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);enhancer.setStrategy(new BeanFactoryAwareGeneratorStrategy(classLoader));enhancer.setCallbackFilter(CALLBACK_FILTER);enhancer.setCallbackTypes(CALLBACK_FILTER.getCallbackTypes());return enhancer;
    }
    1. 回调拦截器

    BeanMethodInterceptor:处理 @Bean 方法调用。

    BeanFactoryAwareMethodInterceptor:处理依赖注入。

    3.3、底层机制

    1、代理创建时机

    1. 在容器启动时,Spring检测到@Configuration

    2. 通过ConfigurationClassPostProcessor处理配置类

    3. 使用CGLIB生成子类代理

    2、代理类的工作方式

    生成的代理类会:

    1. 首次调用@Bean方法时,将返回的Bean注册到容器

    2. 后续调用相同方法时,直接从容器返回已注册的Bean

    3. 拦截所有@Bean方法调用,确保通过容器获取Bean

    3.4、如何验证代理行为

    示例代码

    @Configuration
    public class ConfigA {@Beanpublic B b() {return new B();}
    }@Component
    public class ConfigB {@Bean public C c() {return new C();}
    }

    测试验证

    @SpringBootTest
    public class ConfigTest {@Autowiredprivate ApplicationContext context;@Testpublic void testProxy() {// @Configuration类会被代理System.out.println(context.getBean(ConfigA.class).getClass()); // 输出: class com.example.ConfigA$$EnhancerBySpringCGLIB$$xxx// @Component类不会被代理System.out.println(context.getBean(ConfigB.class).getClass());// 输出: class com.example.ConfigB}
    }

    4、性能考量

    4.1 启动时间影响(测试数据)

    4.2 方法调用开销(纳秒级测量)

    • 代理创建开销:启动时会增加少量开销

    • 运行时性能:方法调用有轻微间接开销

    • 优化方案:对于不需要方法间调用的简单配置,可使用@Component+@Bean

    5、最佳实践建议

    1、使用@Configuration

    1. 需要定义多个相互依赖的Bean

    2. 需要完整的Spring配置功能

    3. 使用@Enable*系列注解

    2、使用@Component+@Bean

    1. 只有简单的Bean定义

    2. 不需要方法间调用

    3. 想避免代理开销

    3、禁用代理(特殊场景):

    @Configuration(proxyBeanMethods = false)
    public class MyConfig {// 此时行为类似于@Component
    }

    总结

            Spring为@Configuration生成代理是为了保证Bean的单例性和正确的依赖管理,这是Spring容器可靠性的重要基础设计。

    相关文章:

  • 数字孪生和3D可视化有什么区别?一文解析核心差异
  • 5.24 note
  • C++ 日志系统实战第六步:性能测试
  • 安全生态与职业跃迁
  • 数学建模day01
  • 20200201工作笔记常用命令要整理
  • 45道工程模块化高频题整理(附答案背诵版)
  • 讯联文库开发日志(五)登录拦截校验
  • Redis从入门到实战 - 原理篇
  • ajax中get和post的区别,datatype返回的数据类型有哪些?
  • OpenEuler-Apache服务原理
  • 汽车充电桩专用ASCP210系列电气防火限流式保护器
  • 向量数据库该如何选择?Milvus 、ES、OpenSearch 快速对比:向量搜索能力与智能检索引擎的应用前景
  • 基于Java的话剧购票小程序【附源码】
  • 怎么判断一个Android APP使用了taro 这个跨端框架
  • 华为OD机试_2025 B卷_爱吃蟠桃的孙悟空(Python,100分)(附详细解题思路)
  • 【PalladiumZ2 使用专栏 3 -- 信号值的获取与设置 及 memory dump 与 memory load】
  • PyQt学习系列09-应用程序打包与部署
  • 【学习笔记】Sophus (Python) 使用文档
  • TASK05【Datawhale 组队学习】系统评估与优化
  • 滨江区住房和城乡建设局网站/郑州网站优化顾问
  • 建设网站必须用dns/seo是什么专业
  • 吉林做网站的公司/什么叫营销
  • wordpress固定链接中文/中和seo公司
  • jsp ajax网站开发典型实例 pdf/百度开户返点
  • 网站建设都包括什么科目/百度seo排名优化公司哪家好