欢迎访问悦橙教程(wld5.com),关注java教程。悦橙教程  java问答|  每日更新
页面导航 : > > 文章正文

springboot@Configuration和@Componment的区别及说明,

来源: javaer 分享于  点击 40870 次 点评:23

springboot@Configuration和@Componment的区别及说明,


目录
  • @Configuration和@Componment的区别
    • @Configuration
    • 第一段代码会像我们期望的一样正常运行
    • 第二段代码在执行driver()
    • 在上面的第二段代码中
  • 总结

    @Configuration和@Componment的区别

    @Configuration

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component
    public @interface Configuration {
        @AliasFor(
            annotation = Component.class
        )
        String value() default "";
    }
    
    public class Car {
    
        private int id;
    
        private String name;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
    }
    
    public class Driver {
    
        private int id;
    
        private String name;
    
        private Car car;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Car getCar() {
            return car;
        }
    
        public void setCar(Car car) {
            this.car = car;
        }
    
    }
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class MyTestConfig {
    
        @Bean
        public Driver driver() {
            Driver driver = new Driver();
            driver.setId(1);
            driver.setName("driver");
            driver.setCar(car());
            return driver;
        }
    
        @Bean
        public Car car() {
            Car car = new Car();
            car.setId(1);
            car.setName("car");
            return car;
        }
    
    }
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Component
    public class MyTestConfig {
        @Bean
        public Driver driver() {
            Driver driver = new Driver();
            driver.setId(1);
            driver.setName("driver");
            driver.setCar(car());
            return driver;
        }
        @Bean
        public Car car() {
            Car car = new Car();
            car.setId(1);
            car.setName("car");
            return car;
        }
    
    }
    

    上面两段代码除MyTestConfig类上的注解不同之外其他都相同,但Spring对两者的处理方式是完全不一样的。

    第一段代码会像我们期望的一样正常运行

    因为driver()这段代码中driver.setCar(car())方法会由Spring代理执行,

    Spring发现方法所请求的Bean已经在容器中,那么就直接返回容器中的Bean。

    所以全局只有一个Car对象的实例。

    第二段代码在执行driver()

    时driver.setCar(car())不会被Spring代理,会直接调用car()方法获取一个全新的Car对象实例,所以全局会有多个Car对象的实例

    造成这种差异的原因如下:

    概括就是 @Configuration 中所有带 @Bean

    注解的方法都会被动态代理,因此调用该方法返回的都是同一个实例。

    其工作原理是:如果方式是首次被调用那么原始的方法体会被执行并且结果对象会被注册到Spring上下文中,之后所有的对该方法的调用仅仅只是从Spring上下文中取回该对象返回给调用者。

    在上面的第二段代码中

    driver.setCar(car())只是纯JAVA方式的调用,多次调用该方法返回的是不同的对象实例。

    要修正第二段代码中的问题,可以使用@Autowired如下所示:

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.stereotype.Component;
    
    //@Configuration
    @Component
    public class MyTestConfig2 {
    
        @Autowired
        Car car;
        
        @Bean
        public Driver driver() {
            Driver driver = new Driver();
            driver.setId(1);
            driver.setName("driver");
            driver.setCar(car);
            return driver;
        }
    
        @Bean
        public Car car() {
            Car car = new Car();
            car.setId(1);
            car.setName("car");
            return car;
        }
    
    }
    

    总结

    1. 通过@Configuration或者@Componment注解的类默认是非懒加载,可以使用@Lazy或者在@Bean上@Lazy开启懒加载;

    2. 通过@Configuration注解的类默认会被CGLIB动态代理,所有被 @Bean 注解标记的方法将来都是通过代理方法进行调用,在该类中使用@Bean时为单列;

    3. 通过@Componment注解的类默认不会产生动态代理,在该类中使用@Bean,是多实例的。

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持3672js教程。

    您可能感兴趣的文章:
    • SpringBoot中的@ConfigurationProperties注解解析
    • SpringBoot配置类中@Configuration和@Bean的作用
    • SpringBoot中@ConfigurationProperties注解的使用与源码详解
    • SpringBoot中@EnableAutoConfiguration和@Configuration的区别
    • SpringBoot中的@Configuration注解详解
    相关栏目:

    用户点评