Spring/Spring-Boot 学习 @Configuration 和 @Component 区别

转自 Spring @Configuration 和 @Component 区别

内部原理其实也是挺复杂的,用最简单的语言汇总以下两者的区别,只要理解的就ok了,深入理解可以看这篇博客 Spring @Configuration 和 @Component 区别
** @Configuration中所有带 @Bean 注解的方法都会被动态代理,因此调用该方法返回的都是同一个实例。**
如果看@Configuration 注解的定义代码,会发现它本质上还是@Component,因此<context:component-scan/>或者 @ComponentScan都能处理@Configuration注解的类。
@Configuration注解的bean使用cglib代理,都已经变成了增强的类。

案例描述

@Configuration + @Bean 注解方法执行策略

@Configuration
public class MyBeanConfig {
 
    @Bean
    public Country country(){
        return new Country();
    }
 
    @Bean
    public UserInfo userInfo(){
        return new UserInfo(country());
    }
 
}

特别重要!!特别重要!!--》直接调用 country() 方法返回的是同一个实例,因为注解是@Configuration增强版本类
但是如果是变成@Component之后,此时返回的就不是一个实例了,每次都会创建一个新的实例。因为@Component 注解并没有通过cglib来代理@Bean方法的调用

@Component注解

@Component
public class MyBeanConfig {
 
    @Bean
    public Country country(){
        return new Country();
    }
 
    @Bean
    public UserInfo userInfo(){
        return new UserInfo(country());
    }
}

修正版本:如何让@Component注解返回的也是同一个实例(用@Autowired 注入)

  • 这种方式可以保证使用的同一个 Country 实例。
@Component
public class MyBeanConfig {
 
    @Autowired
    private Country country;
 
    @Bean
    public Country country(){
        return new Country();
    }
 
    @Bean
    public UserInfo userInfo(){
        return new UserInfo(country);
    }
}

其他相关知识点

@Configuration 标记的类必须符合下面的要求:

  • 配置类必须以类的形式提供(不能是工厂方法返回的实例),允许通过生成子类在运行时增强(cglib 动态代理)。
  • 配置类不能是 final 类(没法动态代理)。
  • 配置注解通常为了通过 @Bean 注解生成 Spring 容器管理的类,
  • 配置类必须是非本地的(即不能在方法中声明,不能是 private)。
  • 任何嵌套配置类都必须声明为static
  • @Bean 方法可能不会反过来创建进一步的配置类(也就是返回的 bean 如果带有 @Configuration,也不会被特殊处理,只会作为普通的 bean)。
posted @ 2019-11-21 14:49  lllunaticer  阅读(531)  评论(0编辑  收藏  举报