Spring boot 配置文件,配置注解详解 (properties 和yml )

从其他框架来看 我们都有自己的配置文件, hibernate 有 hbm,mybatis 有 properties, 同样, Spring boot 也有全局配置文件。

Springboot 使用一个全局的配置文件,而且配置文件的名字是固定的。 有两种

  • application.properties
  • application.yml 

springboot 配置文件的作用是用来 修改 SpringBoot 自动配置的默认值;SpringBoot 在底层都给我们自动配置好; 像我们 Tomcat 启动 默认配置端口是 8080 . 如果要修改, 我们就在这两个文件的一种中来修改,

  • YML (也叫 YAML :  YAM Ain't  Markup Language)

      YAML Ain't Markup Language 这是一个递归写法 ;

  1. YAML  A Markup Language:是一个标记语言
  2. YAML   isn't Markup Language:不是一个标记语言;

标记语言: 

   我们以前用的配置文件,大多都使用 xxxx.xml  文件 ;

 YAML  : 是一种以数据为中心的配置文件, 比 json,xml  等更适合做配置文件 

举个栗子:

以 修改端口为例 : 

yml :

server:
port: 8081
xml :
<server>
<port>8081</port>
</server>
 xml 配置 将太多的浪费在了标签上面。

 yml 基本语法:

k:(空格)v:表示一对键值对(空格必须有);

 以  空格  的缩进来控制层级关系;只要是左对齐的一列数据,都是同一个层级的

server:
    port: 8081
    path: /hello
属性和值也是大小写敏感;

值的写法: 

  • 字面量:普通的值(数字,字符串,布尔)

 k: v:字面直接来写;

字符串默认不用加上单引号或者双引号;

"":双引号;不会转义字符串里面的特殊字符;特殊字符会作为本身想表示的意思 

    name:   "zhangsan \n lisi":输出;zhangsan 换行  lisi

 '':单引号;会转义特殊字符,特殊字符最终只是一个普通的字符串数据

name:   ‘zhangsan \n lisi’:输出;zhangsan \n  lisi
  • 对象、Map(属性和值)(键值对):

 k: v:在下一行来写对象的属性和值的关系;注意缩进
​        对象还是 k: v 的方式

1
2
3
4
5
6
friends:
        lastName: zhangsan
        age: 20
行内写法:
 
friends: {lastName: zhangsan,age: 18}
  •   数组(List、Set):

用 -  值表示数组中的一个元素

1
2
3
4
pets:
 - cat
 - dog
 - pig<br><br>行内写法<br>pets: [cat,dog,pig]
  •   配置文件注入

javaBean :

可以导入配置文件处理器依赖,以后编写配置就会有代码提示;

代码展示配置文件注入属性值 : 

 1 package com.example.webservice.bean;
 2 
 3 import org.springframework.boot.context.properties.ConfigurationProperties;
 4 import org.springframework.stereotype.Component;
 5 
 6 import java.util.Date;
 7 import java.util.List;
 8 import java.util.Map;
 9 
10 /**
11  *
12  * ConfigurationProperties(prefix ="person") 将本类中的所有属性和配置文件中的相关配置进行绑定
13  * prefix ="person  表示对哪个文件进行绑定
14  * Component 表示这是一个容器, 只有在容器中  ConfigurationProperties 才能使用
15 */
16 @Component
17 @ConfigurationProperties(prefix = "person")
18 public class Person {
19 
20      private String name;
21      private Integer age;
22      private boolean man;
23      private Date birth;
24      private Map<String,Object>map;
25      private List<Object>list ;
26      private Son son ;
27 
28 ..... 省略 get/set  以及 toString 方法 
29 
30 }
31 
32 
33 package com.example.webservice.bean;
34 
35 public class Son {
36 
37     private String name;
38     private Integer age ;
39 
40     public String getName() {
41         return name;
42     }
43 
44     public Integer getAge() {
45         return age;
46     }
47 
48     public void setName(String name) {
49         this.name = name;
50     }
51 
52     public void setAge(Integer age) {
53         this.age = age;
54     }
55 
56     @Override
57     public String toString() {
58         return "Son{" + "name='"+ name +'\'' +", age="+ age +'}';
59     }
60 }
61 
62 
63 properties 文件绑定的写法 
64 #注释方法 Ctrl + /
65 person.name=爸爸
66 person.age=45
67 person.man=true
68 person.birth=2019/8/8
69 person.map.k1=h1
70 person.map.k2=h2
71 person.list=a,1,son
72 person.son.name=儿子
73 person.son,age=20
74 
75 
76 yml 文件绑定的写法: 
77 
78 person:
79   name: 爸爸
80   age: 25
81   birth: 2018/2/8
82   man: true
83   list:
84     - a
85     - 2
86     - son
87   map: {key1:value1,key2:value2}
88   son:
89     name: 儿子
90     age: 5
测试类 :
在我们的 test 文件夹下 :
package com.example.webservice;
import com.example.webservice.bean.Person;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class WebserviceApplicationTests {
@Autowired
Person person;
@Test
public void contextLoads() { // 直接运行这个方法 ,而不是运行整个程序
System.out.println(person);
System.out.println("********************************************************");
}

 控制台打印结果 (使用的 yml 配置文件)

properties 配置文件在 idea 中默认 utf-8 可能会乱码 。因为 spring properties  默认是 ASCII 码 ,所以需要将 properties  默认编码改为 UTP-8 ,再√上旁边的 将其运行时转换为 ASCII 码;再输入中文就好了

都改成 utf-8 ,再输入中文就好了。

  • @Value 获取值和 @ConfigurationProperties 获取值比较

 |                                     | @ConfigurationProperties                | @Value |
| 功能                             |   批量注入配置文件中的属性             | 一个个指定  |
| 松散绑定(松散语法) | 支持                                                  | 不支持    |
| SpEL                             | 不支持                                              | 支持     |
| JSR303 数据校验          | 支持                                                  | 不支持    |
| 复杂类型封装               | 支持                                                  | 不支持    |

配置文件 yml 还是 properties 他们都能获取到值;
如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用 @Value;
如果说,我们专门编写了一个 javaBean 来和配置文件进行映射,我们就直接使用 @ConfigurationProperties;

  •  配置文件注入值数据校验

@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
 * &lt;bean class="Person"&gt;
 *      &lt;property name="name" value="字面量/${key}从环境变量、配置文件中获取值/#{SpEL}"&gt;&lt;/property&gt;
 * &lt;bean/&gt;
 </span><span style="color: rgba(0, 128, 0, 1)">*/</span>

//name 必须是邮箱格式
@Email
//@Value("${person.name}")
private String name;
//@Value("#{11*2}")
private Integer age;
//@Value("true")
private Boolean boss;

</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> Date birth;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> Map&lt;String,Object&gt;<span style="color: rgba(0, 0, 0, 1)"> maps;
</span><span style="color: rgba(0, 0, 255, 1)">private</span> List&lt;Object&gt;<span style="color: rgba(0, 0, 0, 1)"> lists;
</span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> Dog dog;

。。。。。get/set /toString

  •  @PropertySource&@ImportResource&@Bean

  @PropertySource:加载指定的配置文件;

/**
 * 将配置文件中配置的每一个属性的值,映射到这个组件中
 * @ConfigurationProperties:告诉 SpringBoot 将本类中的所有属性和配置文件中相关的配置进行绑定;
 *      prefix = "person":配置文件中哪个下面的所有属性进行一一映射
 *
 * 只有这个组件是容器中的组件,才能容器提供的 @ConfigurationProperties 功能;
 *  @ConfigurationProperties(prefix = "person") 默认从全局配置文件中获取值;
 *
 */
@PropertySource(value = {"classpath:person.properties"})
@Component
@ConfigurationProperties(prefix = "person")
//@Validated
public class Person {
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
 * &lt;bean class="Person"&gt;
 *      &lt;property name="name" value="字面量/${key}从环境变量、配置文件中获取值/#{SpEL}"&gt;&lt;/property&gt;
 * &lt;bean/&gt;
 </span><span style="color: rgba(0, 128, 0, 1)">*/</span>

//name 必须是邮箱格式
// @Email
//@Value("${person.name}")
private String name;
//@Value("#{11*2}")
private Integer age;
//@Value("true")
private Boolean boss;

<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"></a></span></div></div>
<ul>
<li>
<h3>&nbsp;@ImportResource:导入Spring的配置文件,让配置文件里面的内容生效;<button class="cnblogs-toc-button" title="显示目录导航" aria-expanded="false"></button></h3>
</li>
</ul>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"></a></span></div>
<pre><span style="color: rgba(0, 0, 0, 1)">Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;

想让Spring的配置文件生效,加载进来;就要将 @</span>ImportResource <span style="color: rgba(0, 0, 0, 1)">标注在一个配置类上

@ImportResource(locations </span>= {"classpath:beans.xml"<span style="color: rgba(0, 0, 0, 1)">})//类路径上添加配置类的路径
导入Spring的配置文件让其生效<br>
不来编写Spring的配置文件  ,下面这就是我们通常的Spring配置类文件</span></pre>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"></a></span></div>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"<span style="color: rgba(0, 0, 0, 1)">
       xmlns:xsi</span>="http://www.w3.org/2001/XMLSchema-instance"<span style="color: rgba(0, 0, 0, 1)">
       xsi:schemaLocation</span>="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"&gt;
    &lt;bean id="helloService" <span style="color: rgba(0, 0, 255, 1)">class</span>="com.example.webservice.controller.Hello"&gt;&lt;/bean&gt;
&lt;/beans&gt;</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"></a></span></div></div>
<pre><span style="color: rgba(0, 0, 0, 1)">SpringBoot推荐给容器中添加组件的方式;推荐使用全注解的方式

</span>1、配置类**@Configuration**------&gt;<span style="color: rgba(0, 0, 0, 1)">Spring配置文件

</span>2<span style="color: rgba(0, 0, 0, 1)">、使用@Bean给容器中添加组件
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
 * @Configuration:指明当前类是一个配置类;就是来替代之前的Spring配置文件
 *
 * 在配置文件中用&lt;bean&gt;&lt;bean/&gt;标签添加组件
 *
 </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
@Configuration
</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> MyAppConfig {

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">将方法的返回值添加到容器中;容器中这个组件默认的id就是方法名</span>
<span style="color: rgba(0, 0, 0, 1)">    @Bean
    </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> HelloService helloService02(){
        System.out.println(</span>"配置类@Bean给容器中添加组件了..."<span style="color: rgba(0, 0, 0, 1)">);
        </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> HelloService();
    }
}</span></pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"></a></span></div></div>
<ul>
<li>
<h2>配置文件占位符<button class="cnblogs-toc-button" title="显示目录导航" aria-expanded="false"></button></h2>
</li>
</ul>
<p>&nbsp;1、随机数</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> ${random.value}、${random.<span style="color: rgba(0, 0, 255, 1)">int</span>}、${random.<span style="color: rgba(0, 0, 255, 1)">long</span><span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)">2</span> ${random.<span style="color: rgba(0, 0, 255, 1)">int</span>(10)}、${random.<span style="color: rgba(0, 0, 255, 1)">int</span>[1024,65536]}</pre>
</div>
<p>&nbsp;2、占位符获取之前配置的值,如果没有可以是用:指定默认值</p>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"></a></span></div>
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 0, 1)">properties
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> person.name=<span style="color: rgba(0, 0, 0, 1)">张三${random.uuid}
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> person.age=${random.<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">}
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> person.birth=2017/12/15
<span style="color: rgba(0, 128, 128, 1)"> 5</span> person.boss=<span style="color: rgba(0, 0, 255, 1)">false</span>
<span style="color: rgba(0, 128, 128, 1)"> 6</span> person.maps.k1=<span style="color: rgba(0, 0, 0, 1)">v1
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> person.maps.k2=14
<span style="color: rgba(0, 128, 128, 1)"> 8</span> person.lists=<span style="color: rgba(0, 0, 0, 1)">a,b,c<br></span></pre>
<pre><span>// 如果没有hello这个属性, 则会直接输出</span></pre>
<pre><span>${person.hello} , 如果加了</span></pre>
<pre><span>${person.hello:hello}_dog   则会直接赋值 输出</span></pre>
<pre><span>hello_dog </span></pre>
<pre><span style="color: rgba(0, 128, 128, 1)"> 9</span> person.dog.name=<span style="color: rgba(0, 0, 0, 1)">${person.hello:hello}_dog  <br><br></span><span style="color: rgba(0, 128, 128, 1)">10</span> person.dog.age=15</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"></a></span></div></div>
<p>3、Profile<br>1、多Profile文件<br>
我们在主配置文件编写的时候,文件名可以是&nbsp;&nbsp;&nbsp;application-{profile}.properties/yml<br>springboot默认使用配置文件为application.properties;</p>
<p>所以我们在然后在application.properties配置文件中 激活自定义的环境配置文件就可以了从application.properties 加载到application-dev.properties 文件了</p>
<p class="md-end-block md-focus"><span class="md-expand">在配置文件中指定 spring.profiles.active=dev</span></p>
<p class="md-end-block md-focus"><span class="md-expand"><img src="http://masterfile.aigcbbs.cn/Fttcd81k76jxI6LaDD7EQV2aPLXf" alt=""><img src="http://masterfile.aigcbbs.cn/FmLhjcv8sm0V_Y9ry60lICw5vLdq" alt="" class="medium-zoom-image"></span></p>
<p>&nbsp;2、yml支持多文档块方式</p>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"></a></span></div>
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> <span style="color: rgba(0, 0, 0, 1)">server:
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span>   port: 8081
<span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 0, 1)">spring:
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 0, 0, 1)">  profiles:
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 0, 1)">    active: prod  表示当前激活使用哪个环境  --- 表示环境的分割 ,分成不同的文档块。
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> ---
<span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">server:
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span>   port: 8083
<span style="color: rgba(0, 128, 128, 1)"> 9</span> <span style="color: rgba(0, 0, 0, 1)">spring:
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)">  profiles: dev
</span><span style="color: rgba(0, 128, 128, 1)">11</span> ---
<span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">server:
</span><span style="color: rgba(0, 128, 128, 1)">13</span>   port: 8084
<span style="color: rgba(0, 128, 128, 1)">14</span> <span style="color: rgba(0, 0, 0, 1)">spring:
</span><span style="color: rgba(0, 128, 128, 1)">15</span>   profiles: prod  #指定属于哪个环境</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"></a></span></div></div>
<p>4、激活指定profile<br>
​&nbsp; &nbsp; 1、在配置文件中指定&nbsp;&nbsp;spring.profiles.active=dev<br>
​&nbsp;&nbsp;&nbsp;&nbsp;2、命令行:<br>
​&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;java -jar spring-boot-02-config-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev;<br>
​&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;可以直接在测试的时候,配置传入命令行参数 ,打包好的项目运行的时候指定我们的环境:</p>
<p><img src="http://masterfile.aigcbbs.cn/Fg0wt48187GNjPE6j1aBTvsMiDPY" alt="" class="medium-zoom-image"></p>
<p>
​&nbsp;&nbsp;&nbsp;&nbsp;3、虚拟机参数; 在运行的时候 选择Editor configrations</p>
<p><img src="http://masterfile.aigcbbs.cn/FhkgE4FN-Dc9mIEOUtnU63DWIWmr" alt="" class="medium-zoom-image"></p>
<p><img src="http://masterfile.aigcbbs.cn/FhBkFyHOAzohCOXk8twBjpx_AzHu" alt="" class="medium-zoom-image"></p>
<p>&nbsp; -Dspring.profiles.active=dev&nbsp; &nbsp;&nbsp;</p>
<p>5、配置文件加载位置</p>
<div class="cnblogs_code">
<p>springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件<br>–file:./config/      文件路径config目录---&gt;最高优先级<br>–file:./           文件路径根目录---&gt;其次 <br>–classpath:/config/ 类路径config目录---&gt;再其次 <br>–classpath:/     类路径根目录---&gt;最低优先级</p>






</div>
<p> 优先级由高到底,高优先级的配置会覆盖低优先级的配置;<br>SpringBoot会从这四个位置全部加载主配置文件:互补配置;<br>我们还可以通过spring.config.location来改变默认的配置文件位置<br>项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认加载的这些配置文件共同起作用形成互补配置;<br>&nbsp;进入命令行 :</p>
<p> java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --spring.config.location=G:/application.properties(properties的硬盘文件目录)<br><br>6、外部配置加载顺序<br>SpringBoot也可以从以下位置加载配置; 优先级从高到低;高优先级的配置覆盖低优先级的配置,所有的配置会形成互补配置<br>1.命令行参数<br>
所有的配置都可以在命令行上进行指定<br>
java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --server.port=8087&nbsp;&nbsp;--server.context-path=/abc<br>
多个配置用空格分开; --配置项=值<br>
2.来自java:comp/env的JNDI属性<br>
3.Java系统属性(System.getProperties())<br>
4.操作系统环境变量<br>
5.RandomValuePropertySource配置的random.*属性值<br><br>由jar包外向jar包内进行寻找;<br><br>优先加载带profile<br><br>7.jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件<br><br>8.jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件<br><br>再来加载不带profile<br><br>9.jar包外部的application.properties或application.yml(不带spring.profile)配置文件<br><br>10.jar包内部的application.properties或application.yml(不带spring.profile)配置文件<br><br>
11.@Configuration注解类上的@PropertySource<br><br>
12.通过SpringApplication.setDefaultProperties指定的默认属性<br><br>
所有支持的配置加载来源;<br><br><a href="https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/htmlsingle/#boot-features-external-config" target="_blank" rel="noopener nofollow">[参考官方文档]</a><br><br></p>
<ul>
<li>
<h2>自动配置原理<button class="cnblogs-toc-button" title="显示目录导航" aria-expanded="false"></button></h2>


































</li>


































</ul>
<p><br>
配置文件到底能写什么?怎么写?自动配置原理;<br><br><a href="https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/htmlsingle/#common-application-properties" target="_blank" rel="noopener nofollow">[配置文件能配置的属性参照]</a><br><br>&nbsp;1、**自动配置原理:<br><br>
1)、SpringBoot启动的时候加载主配置类,开启了自动配置功能 ==@EnableAutoConfiguration==<br><br>2)、@EnableAutoConfiguration 作用:**<br><br>
&nbsp;-&nbsp;&nbsp;利用EnableAutoConfigurationImportSelector给容器中导入一些组件?<br><br>
-&nbsp;可以查看selectImports()方法的内容;<br><br>
-&nbsp;List&lt;String&gt; configurations = getCandidateConfigurations(annotationMetadata,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;attributes);获取候选的配置<br>
&nbsp;&nbsp;&nbsp;&nbsp;SpringFactoriesLoader.loadFactoryNames()<br>
&nbsp;&nbsp;&nbsp;&nbsp;扫描所有jar包类路径下&nbsp;&nbsp;META-INF/spring.factories<br>
&nbsp;&nbsp;&nbsp;&nbsp;把扫描到的这些文件的内容包装成properties对象<br>
&nbsp;&nbsp;&nbsp;&nbsp;从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加在容器中<br><br>将 类路径下&nbsp;&nbsp;META-INF/spring.factories 里面配置的所有EnableAutoConfiguration的值加入到了容器中;</p>
<div class="cnblogs_code"><img id="code_img_closed_509448c3-1945-4cc6-8db8-cd98dfe0075b" class="code_img_closed" src="http://masterfile.aigcbbs.cn/FhTMnKOYjGOl-mq80LMrYwumVWPU" alt=""><img id="code_img_opened_509448c3-1945-4cc6-8db8-cd98dfe0075b" class="code_img_opened" style="display: none" src="http://masterfile.aigcbbs.cn/FlekE2mLdL_Egw6LG3kDnv0jEf0N" alt="">
<div id="cnblogs_code_open_509448c3-1945-4cc6-8db8-cd98dfe0075b" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">```properties
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration</span>=<span style="color: rgba(0, 0, 0, 1)">\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,\
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.OAuth2AutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.social.SocialWebAutoConfiguration,\
org.springframework.boot.autoconfigure.social.FacebookAutoConfiguration,\
org.springframework.boot.autoconfigure.social.LinkedInAutoConfiguration,\
org.springframework.boot.autoconfigure.social.TwitterAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration
```</span></pre>
</div>
<span class="cnblogs_code_collapse">View Code</span></div>
<p>&nbsp;</p>
<p>&nbsp;每一个这样的&nbsp;&nbsp;xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中;用他们来做自动配置;</p>
<p>&nbsp;&nbsp;3)、每一个自动配置类进行自动配置功能;<br>
<br>
4)、以HttpEncodingAutoConfiguration(Http编码自动配置)**为例解释自动配置原理;</p>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"></a></span></div>
<pre>@Configuration   <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件</span>
@EnableConfigurationProperties(HttpEncodingProperties.<span style="color: rgba(0, 0, 255, 1)">class</span>)  <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">启动指定类的ConfigurationProperties功能;将配置文件中对应的值和HttpEncodingProperties绑定起来;并把HttpEncodingProperties加入到ioc容器中</span>
<span style="color: rgba(0, 0, 0, 1)">
@ConditionalOnWebApplication </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">Spring底层@Conditional注解(Spring注解版),根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效;    判断当前应用是否是web应用,如果是,当前配置类生效</span>
<span style="color: rgba(0, 0, 0, 1)">
@ConditionalOnClass(CharacterEncodingFilter.</span><span style="color: rgba(0, 0, 255, 1)">class</span>)  <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">判断当前项目有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器;</span>
<span style="color: rgba(0, 0, 0, 1)">
@ConditionalOnProperty(prefix </span>= "spring.http.encoding", value = "enabled", matchIfMissing = <span style="color: rgba(0, 0, 255, 1)">true</span>)  <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">判断配置文件中是否存在某个配置  spring.http.encoding.enabled;如果不存在,判断也是成立的
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的;</span>
<span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> HttpEncodingAutoConfiguration {

      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">他已经和SpringBoot的配置文件映射了</span>
      <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">final</span><span style="color: rgba(0, 0, 0, 1)"> HttpEncodingProperties properties;

   </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">只有一个有参构造器的情况下,参数的值就会从容器中拿</span>
      <span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
        </span><span style="color: rgba(0, 0, 255, 1)">this</span>.properties =<span style="color: rgba(0, 0, 0, 1)"> properties;
    }

    @Bean   </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">给容器中添加一个组件,这个组件的某些值需要从properties中获取</span>
    @ConditionalOnMissingBean(CharacterEncodingFilter.<span style="color: rgba(0, 0, 255, 1)">class</span>) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">判断容器没有这个组件?</span>
    <span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> CharacterEncodingFilter characterEncodingFilter() {
        CharacterEncodingFilter filter </span>= <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> OrderedCharacterEncodingFilter();
        filter.setEncoding(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.properties.getCharset().name());
        filter.setForceRequestEncoding(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.properties.shouldForce(Type.REQUEST));
        filter.setForceResponseEncoding(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.properties.shouldForce(Type.RESPONSE));
        </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> filter;
    }
```</span></pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"></a></span></div></div>
<p> 根据当前不同的条件判断,决定这个配置类是否生效.<br><br>
一但这个配置类生效;这个配置类就会给容器中添加各种组件;这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;<br>
5)、所有在配置文件中能配置的属性都是在xxxxProperties类中封装者‘;配置文件能配置什么就可以参照某个功能对应的这个属性类</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)">1</span> @ConfigurationProperties(prefix = "spring.http.encoding")  <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">从配置文件中获取指定的值和bean的属性进行绑定</span>
<span style="color: rgba(0, 128, 128, 1)">2</span> <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> HttpEncodingProperties {
</span><span style="color: rgba(0, 128, 128, 1)">3</span> 
<span style="color: rgba(0, 128, 128, 1)">4</span>    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> Charset DEFAULT_CHARSET = Charset.forName("UTF-8");</pre>
</div>
<p>&nbsp;</p>
<ul>
<li>
<h2><strong><span style="font-size: 18pt">精髓: </span></strong><button class="cnblogs-toc-button" title="显示目录导航" aria-expanded="false"></button></h2>
</li>
</ul>
<p> ​&nbsp; &nbsp;1)、SpringBoot启动会加载大量的自动配置类**<br><br>
​&nbsp; &nbsp;2)、我们看我们需要的功能有没有SpringBoot默认写好的自动配置类;**<br><br>
​&nbsp; &nbsp;3)、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件有,我们就不需要再来配置了)**<br><br>
​&nbsp; &nbsp;4)、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在配置文件中指定这些属性的值;<br>
xxxxAutoConfigurartion:自动配置类;<br>
给容器中添加组件<br>
xxxxProperties:封装配置文件中相关属性;</p>
<p><br>2、细节<br>1、@Conditional派生注解(Spring注解版原生的@Conditional作用)<br>
作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;<br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</p>
<div class="table-wrapper"><table style="height: 303px; width: 577px" border="0">
<tbody>
<tr>
<td>&nbsp;@Conditional扩展注解&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</td>
<td>&nbsp;作用(判断是否满足当前指定条件)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</td>




























</tr>
<tr>
<td>@ConditionalOnJava&nbsp; &nbsp; &nbsp;</td>
<td>系统的java版本是否符合要求&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</td>




























</tr>
<tr>
<td>@ConditionalOnBean&nbsp; &nbsp; &nbsp;&nbsp;</td>
<td>容器中存在指定Bean</td>




























</tr>
<tr>
<td>@ConditionalOnMissingBean&nbsp;</td>
<td>容器中不存在指定Bean</td>




























</tr>
<tr>
<td>@ConditionalOnExpression&nbsp;</td>
<td>满足SpEL表达式指定</td>




























</tr>
<tr>
<td>@ConditionalOnClass&nbsp;</td>
<td>系统中有指定的类&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</td>




























</tr>
<tr>
<td>@ConditionalOnMissingClass&nbsp;&nbsp;</td>
<td>系统中没有指定的类&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</td>




























</tr>
<tr>
<td>@ConditionalOnSingleCandidate</td>
<td>容器中只有一个指定的Bean,或者这个Bean是首选Bean&nbsp;</td>




























</tr>
<tr>
<td>@ConditionalOnProperty</td>
<td>系统中指定的属性是否有指定的值&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</td>




























</tr>
<tr>
<td>@ConditionalOnResource&nbsp; &nbsp;&nbsp;</td>
<td>类路径下是否存在指定资源文件&nbsp;</td>




























</tr>
<tr>
<td>@ConditionalOnWebApplication&nbsp; &nbsp;</td>
<td>当前是web环境&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</td>




























</tr>
<tr>
<td>@ConditionalOnNotWebApplication</td>
<td>&nbsp;当前不是web环境&nbsp; &nbsp;&nbsp;</td>




























</tr>
<tr>
<td>@ConditionalOnJndi&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</td>
<td>JNDI存在指定项&nbsp; &nbsp; &nbsp;</td>




























</tr>




























</tbody>




























</table></div>
<p><br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<br><br>自动配置类必须在一定的条件下才能生效;<br>
我们怎么知道哪些自动配置类生效;<br>我们可以通过启用&nbsp;&nbsp;debug=true属性;来让控制台打印自动配置报告==**,这样我们就可以很方便的知道哪些自动配置类生效;</p>
<div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"></a></span></div>
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span> =========================
<span style="color: rgba(0, 128, 128, 1)"> 2</span> AUTO-<span style="color: rgba(0, 0, 0, 1)">CONFIGURATION REPORT
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> =========================
<span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 0, 0, 1)">Positive matches:(自动配置类启用的)
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> -----------------
<span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">   DispatcherServletAutoConfiguration matched:
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span>       - @ConditionalOnClass found required <span style="color: rgba(0, 0, 255, 1)">class</span> 'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find unwanted <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> (OnClassCondition)
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span>       -<span style="color: rgba(0, 0, 0, 1)"> @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition)
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span>         
<span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)">Negative matches:(没有启动,没有匹配成功的自动配置类)
</span><span style="color: rgba(0, 128, 128, 1)">11</span> -----------------
<span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">   ActiveMQAutoConfiguration:
</span><span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 0, 0, 1)">      Did not match:
</span><span style="color: rgba(0, 128, 128, 1)">14</span>          - @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory'<span style="color: rgba(0, 0, 0, 1)"> (OnClassCondition)
</span><span style="color: rgba(0, 128, 128, 1)">15</span> <span style="color: rgba(0, 0, 0, 1)">   AopAutoConfiguration:
</span><span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 0, 1)">      Did not match:
</span><span style="color: rgba(0, 128, 128, 1)">17</span>          - @ConditionalOnClass did not find required classes 'org.aspectj.lang.annotation.Aspect', 'org.aspectj.lang.reflect.Advice' (OnClassCondition)</pre>
<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"></a></span></div></div>
<p>&nbsp;</p>