美文网首页
@Component和@Configuration的作用和区别

@Component和@Configuration的作用和区别

作者: wyn_做自己 | 来源:发表于2022-04-18 10:00 被阅读0次

    今日份鸡汤:人生从来没有固定的路线,决定你走多远的并不是距离,而是你努力的程度~

    简述:

    其实只要你点击一下@Configuration去看一下他的源码,你就会发现他的底层实现就是@Component注解。
    从Spring3.0,@Component和@Configuration 都可与用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。

    @Configuration注解的配置类有如下要求:
    (1)@Configuration不可以是final类型。
    (2)@Configuration不可以是匿名类。
    (3)嵌套的configuration必须是静态类。

    两者作为配置类的主要区别:

    @Component:会当做配置类,但不会为其生成CGLIB代理class

    @Configuration:会当做配置类,但会为其生成CGLIB代理class

    在获取当前类名时,使用@Component获取的是当前类名;而@Configuration获取的是当前类名+唯一标识(CGLIB代理)

    demo展示:
    @Configuration
    public class MyTestConfig {
    
        @Bean
        public Driver driver(){
            Driver driver = new Driver();
            driver.setName("driver");
            driver.setCar(car());
            return driver;
        }
    
        @Bean
        public Car car(){
            Car car = new Car();
            car.setId(1);
            car.setName("car");
            return car;
        }
    }
    

    测试代码如下

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class TestApplicationTests {
    
        @Autowired
        private Car car;
    
        @Autowired
        private Driver driver;
    
        @Test
        public void contextLoads() {
            boolean result = driver.getCar() == car;
            System.out.println(result ? "同一个car" : "不同的car");
        }
    
    }
    
    使用@Configuration打印结果如下:
    
    同一个car
    
    替换为Component后的打印结果:
    
    不同的car
    
    原理说明:

    从执行结果可以看出来 使用Configuration时在driver和spring容器之中的是同一个对象,而使用Component时是不同的对象。

    造成不同结果的原因是后置处理器ConfigurationClassPostProcessor类中,调用enhanceConfigurationClasses方法时,为被注解@Configuration的类进行CGLIB代理。

    虽然@Component注解也会当做配置类,但是并不会为其生成CGLIB代理Class,所以在生成Driver对象时和生成Car对象时调用car()方法执行了两次new操作,所以是不同的对象。当是@Configuration注解时,生成当前对象的子类Class,并对方法拦截,第二次调用car()方法时直接从BeanFactory之中获取对象,所以得到的是同一个对象。

    相关文章

      网友评论

          本文标题:@Component和@Configuration的作用和区别

          本文链接:https://www.haomeiwen.com/subject/vyzrertx.html