简介

@AutoConfiguration其实就是一个组合注解。因为一个自动配置类往往需要加很多注解,于是乎springboot就将一些经常用到的注解,给组合到一块

@Configuration

@Configuration注解我们经常用,但是我们很少这样用@Configuration(proxyBeanMethods = false),这里的proxyBeanMethods默认是true,但是这里却设置为了false,那么这个属性到底有什么作用??

@Configuration属于spring当中的注解,感兴趣的可以看一下spring源码当中的解释:https://github.com/spring-projects/spring-framework/blob/main/spring-context/src/main/java/org/springframework/context/annotation/Configuration.java

demo1

1
2
3
4
5
6
7
8
9
// @Configuration(proxyBeanMethods = false)
@Configuration(proxyBeanMethods = true)
public class Myconfig {

@Bean
public MyBean myBean() {
return new MyBean();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@RestController
public class TestController {

@Autowired
private Myconfig myconfig;

@Autowired
private MyBean myBean;

@RequestMapping("/test")
public void printImportBeanInfo() {
System.out.println(myBean);
System.out.println(myconfig.myBean());
}
}

当然proxyBeanMethods = true ,Autowired 注入 Myconfig 和 MyBean的实例是同一个(这就是所谓的被代理了),false 则不是同一个对象

问题场景

​ 项目启动时需要加载多个配置类,且需要控制某些配置类的加载顺序。使用@Configuration标注配置类,使用@AutoConfigureAfter、@AutoConfigureBefore设置配置类加载顺序。

  • @AutoConfigurationAfter

​ 表明当前配置类在某一个配置类加载后加载。

  • @AutoConfigurationBefore

​ 表明当前配置类在某一个配置类加载前加载。

问题分析

自动配置类
我们平时引入pom依赖时,这些依赖包的配置会自动注入到Spring容器中。最常见的是会自动加载META-INF下的spring.factories文件中定义的配置类。

自定义配置类
可以简单理解为使用@Configuration注解的类。

@AutoConfigureAfter 和 @AutoConfigureBefore 在自动配置类上才会生效,自定义的配置类是不会生效的。

Spring加载配置文件
方式一:构建ApplicationContext时手动传入配置文件类,可控制配置文件加载顺序。

1
ApplicationContext context = new AnnotationConfigApplicationContext(Config1.class, Config2.class);

方式二:使用@Configuration和@ComponentScan自动扫描配置类,无法控制加载顺序。

要自定义顺序注解的方式是:

@AutoConfigureBefore

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Configuration
public class A_SonConfig {
@Bean
public String config2() {
System.out.println("A_SonConfig");
return "A_SonConfig";
}
}

@Configuration
// 在A_SonConfig.class 类 之前自动配置
@AutoConfigureBefore(A_SonConfig.class)
public class B_ParentConfig {
@Bean
public String config1() {
System.out.println("B_ParentConfig");
return "B_ParentConfig";
}
}

直接启动输出可以看到,配置了没有作用,还是 A_SonConfig 先输出再到 B_ParentConfig;看类名可以猜到springboot 默认是按照类的顺序阿来初始化配置的。

其实还缺少配置:

在resource 新建META-INF/spring.factories

1
2
3
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.springbootdemo.config.B_ParentConfig,\
com.example.springbootdemo.config.A_SonConfig

@AutoConfigureOrder

这个和order 差不多,都是注入的时候排序。数值越小,越靠前

springboot 配置类排序

  1. 先按照字母排序
  2. 按照@AutoConfigureOrder进行排序
  3. 按照 @AutoConfigureBefore和@AutoConfigureAfter排序