参考:https://blog.youkuaiyun.com/weixin_43888891/article/details/127473290
文章目录
一、@Configuration
-
基本作用:Component 级别的注解 ,会将该类下的 @Bean 全部注入到容器中
@Configuration(proxyBeanMethods = false)
1.proxyBeanMethods
是否代理创建 bean 的方法,如果被代理了,每次调用就会返回同个对象,这就是我们可以在做复杂配置的时候可以通过调用方法获取到 bean 的原因,验证代码如下
public class TestBean
{
public TestBean() {
System.out.println("初始化");
}
}
public class TestBean2 {
private final TestBean testBean;
public TestBean2(TestBean testBean) {
this.testBean = testBean;
}
}
public class TestBean3 {
private final TestBean testBean;
public TestBean3(TestBean testBean) {
this.testBean = testBean;
}
}
@Configuration
public class TestConfig
{
@Bean
public TestBean testBean(){
return new TestBean();
}
@Bean
public TestBean2 testBean2() {
return new TestBean2(testBean());
}
@Bean
public TestBean3 testBean3() {
return new TestBean3(testBean());
}
}
(1)设置为 true 时,即默认值
只被执行了一次
(2)设置为 false 时
多次初始化,很显然在这种使用场景下多次初始化是不合理的,如果要使其合理化,那应该使用构造方法注入,如下
@Configuration(proxyBeanMethods = false)
public class TestConfig
{
@Bean
public TestBean testBean(){
return new TestBean();
}
@Bean
public TestBean2 testBean2(TestBean testBean) {
return new TestBean2(testBean);
}
@Bean
public TestBean3 testBean3(TestBean testBean) {
return new TestBean3(testBean);
}
}
结果也是一次初始化,因为这样写它是从 spring 的容器中获取的,容器中有了那就是同一个
二、@AutoConfiguration
- 基本作用,定义由
spring.factories
注入的自动配置类,springboot 3.1 中改为了org.springframework.boot.autoconfigure.AutoConfiguration.imports
,默认为 @Configuration( proxyBeanMethods = false ),由此可知,这样的配置类必须都使用构造注入,不然会会出问题,这机制虽然是默认的,但是也更改不了,源码里写死了
2.1 简单实现(3.1版本)
public class TestConfig
{
public TestConfig() {
System.out.println("init1");
}
@Bean
public TestBean testBean(){
return new TestBean();
}
@Bean
public TestBean2 testBean2(TestBean testBean) {
return new TestBean2(testBean);
}
}
imports 文件中配置对应的类即可
2.2 @AutoConfiguration
- 作用就是修改配置类的一些属性,主要有几个属性,
value
,改变bean
的名称,before
相当于@AutoConfigureBefore
,after
相当于@AutoConfigureAfter
,也就是说如果不需要修改imports
文件中配置类的任何默认行为,这个注解也是可以不写的,但是写一下代码会更清晰一点,注意就是如果只写这个注解没有imports
文件是不行的
2.3 @AutoConfigureBefore
- 可以制定在某个配置前执行,作用就是可以覆盖配置,如下
public class TestConfig
{
@Bean
@ConditionalOnMissingBean
public TestBean testBean(){
return new TestBean();
}
}
public class TestConfig2
{
@Bean
@ConditionalOnMissingBean
public TestBean testBean(){
return new TestBean();
}
}
定义了两个配置类,配置了同个 bean ,正常情况下肯定是报错的,但是这里用 @ConditionalOnMissingBean
防止了重复,现在我希望使用的是 config2 中的 bean,就可以用到 @AutoConfigureBefore
,如下,利用这样的特性我们就可以在定义自己的配置类时去覆盖掉一些默认的配置,一般来说spring-boot 的各种 starter 的默认配置肯定是会加上 @ConditionalOnMissingBean
的,比如你想覆盖 redistemplate,就可以这么写,在自己的配置类上加上 @AutoConfiguration(before = RedisAutoConfiguration.class)
@AutoConfigureBefore(TestConfig.class)
public class TestConfig2
{
@Bean
@ConditionalOnMissingBean
public TestBean testBean(){
System.out.println("使用 bean 2");
return new TestBean();
}
}
2.4 @AutoConfigureAfter :同 @AutoConfigureBefore
2.5 @AutoConfigureOrder:定义更具体的配置顺序,效果也是一样的
@AutoConfigureOrder(value = 1)
public class TestConfig2
{
@Bean
@ConditionalOnMissingBean
public TestBean testBean(){
System.out.println("使用 bean 2");
return new TestBean();
}
}
@AutoConfigureOrder(value = 2)
public class TestConfig
{
@Bean
@ConditionalOnMissingBean
public TestBean testBean(){
System.out.println("使用 bean 1");
return new TestBean();
}
}