Configuration
@Configuration
(包括@Repository<持久层>,@Service<业务层>,@Controller<控制层>)注解本质上还是 @Component
@Configuration可理解为用spring的时候xml里面的<beans>标签
@Bean可理解为用spring的时候xml里面的<bean>标签
Spring Boot不是spring的加强版,所以@Configuration和@Bean同样可以用在普通的spring项目中,而不是Spring Boot特有的,只是在spring用的时候,注意加上扫包配置
加载过程:
Spring 容器在启动时,会加载默认的一些 PostPRocessor,其中就有 ConfigurationClassPostProcessor,这个后置处理程序专门处理带有 @Configuration 注解的类,这个程序会在 bean 定义加载完成后,在 bean 初始化前进行处理。主要处理的过程就是使用 cglib 动态代理增强类,而且是对其中带有 @Bean 注解的方法进行拦截并进行处理,如果BeanFactory中有这个对象的话就直接获取,否者new一个新的再返回。简单说就是@Configuration中所有带@Bean注解的方法都会被动态代理,调用该方法返回的都是同一个实例。
@Configuration public class MyBeanConfig { @Bean public Country country(){ return new Country(); } @Bean public UserInfo userInfo(){ return new UserInfo(country()); } }
相信大多数人第一次看到上面 userInfo() 中调用 country() 时,会认为这里的 Country 和上面 @Bean 方法返回的 Country 可能不是同一个对象,因此可能会通过下面的方式来替代这种方式:
@Autowired
private Country country;
实际上不需要这么做(后面会给出需要这样做的场景),直接调用 country() 方法返回的是同一个实例。
Component
@Component
注解并没有通过 cglib 来代理@Bean
方法的调用,所有没有上面那个拦截并判断的过程,因此像下面这样配置时,就是两个不同的 country。
@Component public class MyBeanConfig { @Bean public Country country(){ return new Country(); } @Bean public UserInfo userInfo(){ return new UserInfo(country()); } }
总结:
@Component
(@Controller和@Service
和@Repository
)用于自动检测和使用类路径扫描自动配置bean。
@Bean
用于显式声明单个bean,而不是让Spring像上面那样自动执行它。它将bean的声明与类定义分离,并允许您精确地创建和配置bean。
如果你想要将第三方库中的组件装配到你的应用中,在这种情况下,是没有办法在它的类上添加@Component注解的,因此就不能使用自动化装配的方案了,但是我们可以使用@Bean。
参考:
https://blog.csdn.net/isea533/article/details/78072133
https://blog.csdn.net/u012260707/article/details/52021265
https://blog.csdn.net/long476964/article/details/80626930