详解Spring中@Component和@Configuration的区别

 更新时间:2023年07月07日 10:03:28   作者:Javaer2Leader  
一直有同学搞不清Spring中@Component和@Configuration这两个注解有什么区别,所以这篇文章小编就给大家简单介绍一下@Component和@Configuration的区别,需要的朋友可以参考下

总结

直接上总结:加了@Configuration的类会被CGLIB进行动态代理,不加或者加@Component注解则不会被代理

正文

首先我们都知道使用Spring的@ComponentScan注解可以扫描到@Configuration和@Component的类,并将其交由Spring容器管理,默认会放入单例池中。

新建了一个BeanConfig类用来测试结果:

@Configuration
public class BeanConfig {
}

通过上下文获取IOC容器中的BeanConfig,发现确实是被CGLIB进行了代理。

执行查看上下文中beanFactory的单例池中确实存在。

将BeanConfig类的@Configuration注解改为@Component后再看一下则显示没有被CGLIB代理。

问题

那么Spring为什么设计@Configuration注解修饰的Bean要被动态代理?

先说结果:Spring的目的是让@Configuration注解的类中被@Bean注解的方法生成的对象是单例,那如何使一个方法每次生成返回的对象都是同一个,代理就是其中一种方式。

首先@Configuration注解的作用是用于定义配置类来替换XML配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法会被用于构建BeanDefinition,初始化Spring容器。

也就是说@Configuration的主要目的是搭配@Bean注解替代XML配置文件来向Spring容器注入Bean。

我们在BeanConfig类中增加两个@Bean注解的方法:

@Configuration
public class BeanConfig {
    //@Scope("prototype")
    @Bean
    public Role role(){
        return new Role();
    }
    @Bean
    public User user(){
        Role r1=role();
        Role r2=role();
        System.out.println(r1==r2);
        return new User();
    }
}

通过Spring的处理,直接调用 @Configuration 注解中bean 方法,获取的就是同一个对象,这样想要直接使用某个@Bean注解的对象就不需要 @Autowired 注入了。

当然你非要在方法上加上注解@Scope("prototype"),每次调用该方法还是会生成不同的对象。

源码

注解配置读取器:向BeanDefinitionMap中添加了7个元素,其中一个就是ConfigurationClassPostProcessor

org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext()

执行所有的BeanFactoryPostProcessor的postProcessorBeanFactory()方法

org.springframework.context.support.AbstractApplicationContext#refresh() 方法中的invokeBeanFactoryPostProcessors(beanFactory) org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanFactory

查找到所有带有 @Configuration 注解的 bean 定义,然后在第二个 for 循环中对类进行增强

org.springframework.context.annotation.ConfigurationClassPostProcessor#enhanceConfigurationClasses

到此这篇关于详解Spring中@Component和@Configuration的区别的文章就介绍到这了,更多相关Spring @Component和@Configuration区别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java 使用Socket正确读取数据姿势

    Java 使用Socket正确读取数据姿势

    这篇文章主要介绍了Java 使用Socket正确读取数据姿势,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • Java中对IO流的全面解析

    Java中对IO流的全面解析

    文章介绍了Java中IO流的分类,字符流和字节流的区别,以及字符流和字节流的常用类和方法,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2025-09-09
  • mybatis一级缓存和二级缓存的区别及说明

    mybatis一级缓存和二级缓存的区别及说明

    这篇文章主要介绍了mybatis一级缓存和二级缓存的区别及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • Java中区别.toString() ,(String),valueOf()方法

    Java中区别.toString() ,(String),valueOf()方法

    这篇文章主要介绍了Java中区别.toString() ,(String),valueOf()方法,需要的朋友可以参考下
    2017-01-01
  • SpringBoot controller接收txt文本文件实现方式

    SpringBoot controller接收txt文本文件实现方式

    文章介绍在Spring Boot Controller中接收文本文件的方法,需使用MultipartFile类并通过@RequestParam注解获取,重点说明了获取文件名、内容及保存文件的常用方法,并强调MultipartFile为接口,需通过注解实例化
    2025-09-09
  • 浅谈servlet与jsp的关系

    浅谈servlet与jsp的关系

    本文主要介绍了servlet与jsp的相关知识,并总结出servlet与jsp之间的关系,具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • java 实现web项目启动加载properties属性文件

    java 实现web项目启动加载properties属性文件

    这篇文章主要介绍了java 实现web项目启动加载properties属性文件,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • IntelliJ IDEA社区版2021.3配置SpringBoot项目详细教程及失败案例

    IntelliJ IDEA社区版2021.3配置SpringBoot项目详细教程及失败案例

    IntelliJ IDEA 2021.3.3是一款集成开发环境,用于Java和其他编程语言的开发,下面这篇文章主要给大家介绍了关于IntelliJ IDEA社区版2021.3配置SpringBoot项目详细教程及失败案例的相关资料,需要的朋友可以参考下
    2024-03-03
  • Java超详细介绍抽象类与接口的使用

    Java超详细介绍抽象类与接口的使用

    在类中没有包含足够的信息来描绘一个具体的对象,这样的类称为抽象类,接口是Java中最重要的概念之一,它可以被理解为一种特殊的类,不同的是接口的成员没有执行体,是由全局常量和公共的抽象方法所组成,本文给大家介绍Java抽象类和接口,感兴趣的朋友一起看看吧
    2022-05-05
  • kafka提交偏移量失败导致重复消费的解决

    kafka提交偏移量失败导致重复消费的解决

    文章主要讨论了在使用Spring Kafka时遇到的`KafkaException`,特别是与消费者组和偏移量提交相关的问题,文章解释了Kafka消费者的心跳机制和`max.poll.interval.ms`配置的作用,并提供了如何在`application.yml`或`application.properties`文件中配置这些参数的示例
    2026-01-01

最新评论