spring中Configuration和Component的区别

spring中Configuration和Component的区别

   Configuration和Component都是Spring中用来注册Bean的注解,两者的目的是一样的,但是,产生的效果略有不同,点开Configuration的注解源码,会发现@Configuration注解还是基于@Component注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";

    boolean proxyBeanMethods() default true;
}
  • (1) @configuration的注解本质还是@component,因此对于@configuration注解标记的bean依然能够通过<context:component-scan/>或者@componentScan进行代理实例化

  • (2)  @configuration注解的bean里面带有@bean注解的方法都会被动态代理,因此调用该方法返回的都是同一个实例,被configuration注解的bean实际是变成一个增强类

  • (3) @configuration是通过cglib来代理@bean方法的使用, @component注解并没有。

使用代码比较两者差异:

@Configuration
public class User {
    private Long id;
    private String name;

    public Long getId() {
        return new Random().nextLong();
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}
@Component
public class CompUser {

    @Bean("user2")
    public User getUser() {
       return new User();
    }
}
@Configuration
public class ConfigUser {

    @Bean("user1")
    public User getUser() {
        return new User();
    }
}
@Configuration
@EnableScheduling
public class CompareConfigAndComp {

    @Autowired
    CompUser compUser;

    @Autowired
    ConfigUser configUser;

    @Scheduled(cron = "0/3 * * * * ?")
    public void task() {
        System.out.println(configUser.getUser()+ ">>>>>>>>>>>>>>>>" + compUser.getUser());
        System.out.println(configUser.getUser().hashCode() + ">>>>>>>>>>>>>>>>" + compUser.getUser().hashCode());
    }
}
@SpringBootApplication
public class WebApplication {

    public static void main(String[] args) {
        SpringApplication.run(WebApplication.class);
    }
}

为了方面上面代码基于springboot框架,引入了spring-boot-starter启动springboot,得到执行结果

2020-01-17 14:31:33.056  INFO 10684 --- [           main] o.s.s.c.ThreadPoolTaskScheduler          : Initializing ExecutorService 'taskScheduler'
2020-01-17 14:31:33.086  INFO 10684 --- [           main] com.fan.springbootdemo.WebApplication    : Started WebApplication in 0.948 seconds (JVM running for 1.34)
1097324923>>>>>>>>>>>>>>>>611542068
1097324923>>>>>>>>>>>>>>>>716476106
1097324923>>>>>>>>>>>>>>>>780865348
1097324923>>>>>>>>>>>>>>>>1804174577
1097324923>>>>>>>>>>>>>>>>1424236400

  会发现@Configuration注解的类中,User对象的hashcode一直不变,说明User对象只被初始化了一次,这说明在注册ConfigUser对象时,就初始化了User对象,而@Component注解的类,每次获取User对象的hashcode都不同,说明@Component不会在注册CompUser对象时就初始化User,而是调用getUser方法才创建.综上,所以当使用场景中,需要一次性初始化所有Bean就使用@configuration,不需要就使用@component

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容