SpringBoot自动配置原理

1 SpringBoot 特点

1.1 依赖管理

  • 父项目做依赖管理
1
2
3
4
5
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
</parent>
  • 无需关注版本号,版本自动仲裁(引入非仲裁版本的jar,需要写版本号)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
父项目的父项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.4.RELEASE</version>
</parent>

父项目的父项目中定义了常用jar 版本号
<properties>
<activemq.version>5.15.13</activemq.version>
<antlr2.version>2.7.7</antlr2.version>
<appengine-sdk.version>1.9.82</appengine-sdk.version>
<artemis.version>2.12.0</artemis.version>
<aspectj.version>1.9.6</aspectj.version>
<assertj.version>3.16.1</assertj.version>
<atomikos.version>4.0.6</atomikos.version>
<awaitility.version>4.0.3</awaitility.version>
<bitronix.version>2.1.4</bitronix.version>
<build-helper-maven-plugin.version>3.1.0</build-helper-maven-plugin.version>
<byte-buddy.version>1.10.14</byte-buddy.version>
<caffeine.version>2.8.5</caffeine.version>
<cassandra-driver.version>4.6.1</cassandra-driver.version>
<classmate.version>1.5.1</classmate.version>
<commons-codec.version>1.14</commons-codec.version>
<commons-dbcp2.version>2.7.0</commons-dbcp2.version>
<commons-lang3.version>3.10</commons-lang3.version>
<commons-pool.version>1.6</commons-pool.version>
<commons-pool2.version>2.8.1</commons-pool2.version>
<couchbase-client.version>3.0.8</couchbase-client.version>
<db2-jdbc.version>11.5.4.0</db2-jdbc.version>
<dependency-management-plugin.version>1.0.10.RELEASE</dependency-management-plugin.version>
<derby.version>10.14.2.0</derby.version>
<dropwizard-metrics.version>4.1.12.1</dropwizard-metrics.version>
<ehcache.version>2.10.6</ehcache.version>
<ehcache3.version>3.8.1</ehcache3.version>
<elasticsearch.version>7.6.2</elasticsearch.version>
<embedded-mongo.version>2.2.0</embedded-mongo.version>
<exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
<flatten-maven-plugin.version>1.2.5</flatten-maven-plugin.version>
<flyway.version>6.4.4</flyway.version>
<freemarker.version>2.3.30</freemarker.version>
<git-commit-id-plugin.version>3.0.1</git-commit-id-plugin.version>
<glassfish-el.version>3.0.3</glassfish-el.version>
<glassfish-jaxb.version>2.3.3</glassfish-jaxb.version>
<groovy.version>2.5.13</groovy.version>
<gson.version>2.8.6</gson.version>
<h2.version>1.4.200</h2.version>
<hamcrest.version>2.2</hamcrest.version>
<hazelcast.version>3.12.9</hazelcast.version>
<hazelcast-hibernate5.version>1.3.2</hazelcast-hibernate5.version>
<hibernate.version>5.4.21.Final</hibernate.version>
<hibernate-validator.version>6.1.5.Final</hibernate-validator.version>
<hikaricp.version>3.4.5</hikaricp.version>
<hsqldb.version>2.5.1</hsqldb.version>
<htmlunit.version>2.40.0</htmlunit.version>
<httpasyncclient.version>4.1.4</httpasyncclient.version>
<httpclient.version>4.5.12</httpclient.version>
<httpcore.version>4.4.13</httpcore.version>
<infinispan.version>10.1.8.Final</infinispan.version>
<influxdb-java.version>2.18</influxdb-java.version>
<jackson-bom.version>2.11.2</jackson-bom.version>
<jakarta-activation.version>1.2.2</jakarta-activation.version>
<jakarta-annotation.version>1.3.5</jakarta-annotation.version>
<jakarta-jms.version>2.0.3</jakarta-jms.version>
<jakarta-json.version>1.1.6</jakarta-json.version>
<jakarta-json-bind.version>1.0.2</jakarta-json-bind.version>
<jakarta-mail.version>1.6.5</jakarta-mail.version>
<jakarta-persistence.version>2.2.3</jakarta-persistence.version>
<jakarta-servlet.version>4.0.4</jakarta-servlet.version>
<jakarta-servlet-jsp-jstl.version>1.2.7</jakarta-servlet-jsp-jstl.version>
<jakarta-transaction.version>1.3.3</jakarta-transaction.version>
<jakarta-validation.version>2.0.2</jakarta-validation.version>
<jakarta-websocket.version>1.1.2</jakarta-websocket.version>
<jakarta-ws-rs.version>2.1.6</jakarta-ws-rs.version>
<jakarta-xml-bind.version>2.3.3</jakarta-xml-bind.version>
<jakarta-xml-soap.version>1.4.2</jakarta-xml-soap.version>
<jakarta-xml-ws.version>2.3.3</jakarta-xml-ws.version>
<janino.version>3.1.2</janino.version>
<javax-activation.version>1.2.0</javax-activation.version>
<javax-annotation.version>1.3.2</javax-annotation.version>
<javax-cache.version>1.1.1</javax-cache.version>
<javax-jaxb.version>2.3.1</javax-jaxb.version>
<javax-jaxws.version>2.3.1</javax-jaxws.version>
<javax-jms.version>2.0.1</javax-jms.version>
<javax-json.version>1.1.4</javax-json.version>
<javax-jsonb.version>1.0</javax-jsonb.version>
<javax-mail.version>1.6.2</javax-mail.version>
<javax-money.version>1.0.3</javax-money.version>
<javax-persistence.version>2.2</javax-persistence.version>
<javax-transaction.version>1.3</javax-transaction.version>
<javax-validation.version>2.0.1.Final</javax-validation.version>
<javax-websocket.version>1.1</javax-websocket.version>
<jaxen.version>1.2.0</jaxen.version>
<jaybird.version>3.0.9</jaybird.version>
<jboss-logging.version>3.4.1.Final</jboss-logging.version>
<jboss-transaction-spi.version>7.6.0.Final</jboss-transaction-spi.version>
<jdom2.version>2.0.6</jdom2.version>
<jedis.version>3.3.0</jedis.version>
<jersey.version>2.30.1</jersey.version>
<jetty-el.version>8.5.54</jetty-el.version>
<jetty-jsp.version>2.2.0.v201112011158</jetty-jsp.version>
<jetty-reactive-httpclient.version>1.1.4</jetty-reactive-httpclient.version>
<jetty.version>9.4.31.v20200723</jetty.version>
<jmustache.version>1.15</jmustache.version>
<johnzon.version>1.2.8</johnzon.version>
<jolokia.version>1.6.2</jolokia.version>
<jooq.version>3.13.4</jooq.version>
<json-path.version>2.4.0</json-path.version>
<json-smart.version>2.3</json-smart.version>
<jsonassert.version>1.5.0</jsonassert.version>
<jstl.version>1.2</jstl.version>
<jtds.version>1.3.1</jtds.version>
<junit.version>4.13</junit.version>
<junit-jupiter.version>5.6.2</junit-jupiter.version>
<kafka.version>2.5.1</kafka.version>
<kotlin.version>1.3.72</kotlin.version>
<kotlin-coroutines.version>1.3.8</kotlin-coroutines.version>
<lettuce.version>5.3.4.RELEASE</lettuce.version>
<liquibase.version>3.8.9</liquibase.version>
<log4j2.version>2.13.3</log4j2.version>
<logback.version>1.2.3</logback.version>
<lombok.version>1.18.12</lombok.version>
<mariadb.version>2.6.2</mariadb.version>
<maven-antrun-plugin.version>1.8</maven-antrun-plugin.version>
<maven-assembly-plugin.version>3.3.0</maven-assembly-plugin.version>
<maven-clean-plugin.version>3.1.0</maven-clean-plugin.version>
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
<maven-dependency-plugin.version>3.1.2</maven-dependency-plugin.version>
<maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
<maven-enforcer-plugin.version>3.0.0-M3</maven-enforcer-plugin.version>
<maven-failsafe-plugin.version>2.22.2</maven-failsafe-plugin.version>
<maven-help-plugin.version>3.2.0</maven-help-plugin.version>
<maven-install-plugin.version>2.5.2</maven-install-plugin.version>
<maven-invoker-plugin.version>3.2.1</maven-invoker-plugin.version>
<maven-jar-plugin.version>3.2.0</maven-jar-plugin.version>
<maven-javadoc-plugin.version>3.2.0</maven-javadoc-plugin.version>
<maven-resources-plugin.version>3.1.0</maven-resources-plugin.version>
<maven-shade-plugin.version>3.2.4</maven-shade-plugin.version>
<maven-source-plugin.version>3.2.1</maven-source-plugin.version>
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
<maven-war-plugin.version>3.2.3</maven-war-plugin.version>
<micrometer.version>1.5.5</micrometer.version>
<mimepull.version>1.9.13</mimepull.version>
<mockito.version>3.3.3</mockito.version>
<mongodb.version>4.0.5</mongodb.version>
<mssql-jdbc.version>7.4.1.jre8</mssql-jdbc.version>
<mysql.version>8.0.21</mysql.version>
<nekohtml.version>1.9.22</nekohtml.version>
<neo4j-ogm.version>3.2.16</neo4j-ogm.version>
<netty.version>4.1.52.Final</netty.version>
<netty-tcnative.version>2.0.34.Final</netty-tcnative.version>
<nio-multipart-parser.version>1.1.0</nio-multipart-parser.version>
<oauth2-oidc-sdk.version>7.1.1</oauth2-oidc-sdk.version>
<nimbus-jose-jwt.version>8.19</nimbus-jose-jwt.version>
<ojdbc.version>19.3.0.0</ojdbc.version>
<okhttp3.version>3.14.9</okhttp3.version>
<oracle-database.version>19.3.0.0</oracle-database.version>
<pooled-jms.version>1.1.2</pooled-jms.version>
<postgresql.version>42.2.16</postgresql.version>
<prometheus-pushgateway.version>0.9.0</prometheus-pushgateway.version>
<quartz.version>2.3.2</quartz.version>
<querydsl.version>4.3.1</querydsl.version>
<r2dbc-bom.version>Arabba-SR7</r2dbc-bom.version>
<rabbit-amqp-client.version>5.9.0</rabbit-amqp-client.version>
<reactive-streams.version>1.0.3</reactive-streams.version>
<reactor-bom.version>Dysprosium-SR12</reactor-bom.version>
<rest-assured.version>3.3.0</rest-assured.version>
<rsocket.version>1.0.2</rsocket.version>
<rxjava.version>1.3.8</rxjava.version>
<rxjava-adapter.version>1.2.1</rxjava-adapter.version>
<rxjava2.version>2.2.19</rxjava2.version>
<saaj-impl.version>1.5.2</saaj-impl.version>
<selenium.version>3.141.59</selenium.version>
<selenium-htmlunit.version>2.40.0</selenium-htmlunit.version>
<sendgrid.version>4.4.8</sendgrid.version>
<servlet-api.version>4.0.1</servlet-api.version>
<slf4j.version>1.7.30</slf4j.version>
<snakeyaml.version>1.26</snakeyaml.version>
<solr.version>8.5.2</solr.version>
<spring-amqp.version>2.2.11.RELEASE</spring-amqp.version>
<spring-batch.version>4.2.4.RELEASE</spring-batch.version>
<spring-data-releasetrain.version>Neumann-SR4</spring-data-releasetrain.version>
<spring-framework.version>5.2.9.RELEASE</spring-framework.version>
<spring-hateoas.version>1.1.2.RELEASE</spring-hateoas.version>
<spring-integration.version>5.3.2.RELEASE</spring-integration.version>
<spring-kafka.version>2.5.6.RELEASE</spring-kafka.version>
<spring-ldap.version>2.3.3.RELEASE</spring-ldap.version>
<spring-restdocs.version>2.0.5.RELEASE</spring-restdocs.version>
<spring-retry.version>1.2.5.RELEASE</spring-retry.version>
<spring-security.version>5.3.4.RELEASE</spring-security.version>
<spring-session-bom.version>Dragonfruit-SR1</spring-session-bom.version>
<spring-ws.version>3.0.10.RELEASE</spring-ws.version>
<sqlite-jdbc.version>3.31.1</sqlite-jdbc.version>
<sun-mail.version>1.6.5</sun-mail.version>
<thymeleaf.version>3.0.11.RELEASE</thymeleaf.version>
<thymeleaf-extras-data-attribute.version>2.0.1</thymeleaf-extras-data-attribute.version>
<thymeleaf-extras-java8time.version>3.0.4.RELEASE</thymeleaf-extras-java8time.version>
<thymeleaf-extras-springsecurity.version>3.0.4.RELEASE</thymeleaf-extras-springsecurity.version>
<thymeleaf-layout-dialect.version>2.4.1</thymeleaf-layout-dialect.version>
<tomcat.version>9.0.38</tomcat.version>
<unboundid-ldapsdk.version>4.0.14</unboundid-ldapsdk.version>
<undertow.version>2.1.4.Final</undertow.version>
<versions-maven-plugin.version>2.7</versions-maven-plugin.version>
<webjars-hal-browser.version>3325375</webjars-hal-browser.version>
<webjars-locator-core.version>0.45</webjars-locator-core.version>
<wsdl4j.version>1.6.3</wsdl4j.version>
<xml-maven-plugin.version>1.0.2</xml-maven-plugin.version>
<xmlunit2.version>2.7.0</xmlunit2.version>
</properties>
  • 可以修改版本号 —— 在当前项目中重写版本号
1
2
3
4
5
<properties>
<mysql.version>5.1.43</mysql.version>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
  • 开发导入 starter 场景启动器

    • spring-boot-starter-* ,*就指某种场景,只要引入了 starter ,这个场景所有常规需要的依赖都会自动引入;
1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

1.2 自动配置

  • 自动配置好 Tomcat

    • 引入 Tomcat 依赖
    • 自动配置
  • 自动配置好 SpringMVC

    • 引入 SpringMVC 全套组件
    • 自动配置好 SpringMVC 常用组件(功能)
  • 自动配置好 Web 常见功能,如:字符编码问题

    • 配置好常见 Web 开发场景
  • 默认包的结构

    • 主程序
  • 各种配置拥有默认值

  • 按需加载所有配置项

2 容器功能

2.1 组件添加

1. @Configuration

  • 基本使用

  • Full 模式与 Lite 模式

    • lite模式包含:

      没有被@Configuration修饰,被@Component修饰
      没有被@Configuration修饰,被@ComponentScan修饰
      没有被@Configuration修饰,被@Import修饰
      没有被@Configuration修饰,被@ImportResource修饰
      没有任何Spring相关注解,类里面有@Bean修饰的方法
      被@Configuration修饰,但是属性proxyBeanMethods = false

    • full模式包含:

      被@Configuration修饰,且属性proxyBeanMethods = true(proxyBeanMethods 默认为true)

    • full模式使用特性:

      full模式下的配置类会被CGLIB代理生成代理类取代原始类型(在容器中)
      full模式下的@Bean方法不能是private和final
      单例scope下不同@Bean方法可以互相引用,达到单实例的语义

    • lite模式使用特性:

      lite模式下的配置类不生成代理,原始类型进入容器
      lite模式下的@Bean方法可以是private和final
      单例scope下不同@Bean方法引用时无法做到单例

  • 示例

    MyConfig.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package site.shaoshao.boot.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import site.shaoshao.boot.bean.Pet;
import site.shaoshao.boot.bean.User;

/**
* 1. 配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例
* 2. 配置类本身也是组件
* 3. 5.2后 proxyBeanMethods:代理bean的方法
* Full(proxyBeanMethods = true)默认
* Lite(proxyBeanMethods = false)
* 组件依赖
*/

/**
proxyBeanMethods这个属性是并不是决定容器中的组件是单例还是多例的。如果说他是true,就是单例。如果说是false,但却不是多
例。当他为true的时候,我们在容器中获取到的对象总是同一个,即便是我们调用了创建对象的方法,那获取到的还是同一个。但是当是多例的
时候,如果我们调用了创建对象的方法,那就不是同一个了。但是我们如果是用getBeans方法去获取的话,那样还是单例的,我们得到的还是同
一个对象。
但是我们这样去思考还是太简单了。其实,proxyBeanMethods代表的是,如果是true的话,那么这个配置类就会被代理了,如果是false
的话,那么就不会被代理。
当我们使用代理对象的时候,调用它的方法,他会检测容器中是不是有了这样的组件,如果有,则不再新建组件,直接将已经有的组件返
回。如果说没有的话,才会新建组件。这样保证了容器中的组件始终就保持单一性。不过这也有一个不好的地方,那就是每次都要检测,会降低
速度。
当不是代理对象的时候,则不会检测,直接创建新的组件了。
*/
@Configuration(proxyBeanMethods = false) //告诉Springboot这是一个配置类 == 配置文件
public class MyConfig {

/**
* 外部无论对配置文类中的这个组件注册方法调用多少次,获取到的都是之前注册到容器中的单实例对象
*/
@Bean //给容器中添加组件。以方法名
public User user01(){
User zhangsan = new User("zhangsan", 18);
//user组件依赖了pet组件
zhangsan.setPet(pet01());
return zhangsan;
}

@Bean("tom")
public Pet pet01(){
return new Pet("tom");
}
}

MainApplication.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package site.shaoshao.boot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import site.shaoshao.boot.bean.Pet;
import site.shaoshao.boot.bean.User;
import site.shaoshao.boot.config.MyConfig;

/**
* 主程序类
*/
@SpringBootApplication
public class MainApplication {
public static void main(String[] args) {
// 返回IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
// 查看容器中组件
String[] names = run.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
// 从容器中获取组件
Pet tom01 = run.getBean("tom", Pet.class);
Pet tom02 = run.getBean("tom", Pet.class);
System.out.println("组件单实例:"+(tom01==tom02));// true

MyConfig bean = run.getBean(MyConfig.class);
User user01 = bean.user01();
User user02 = bean.user01();
//如果@Configuration(proxyBeanMethods = true)代理对象调用方法。springboot总会检查这个组件是否在容器中注册
//保持组件单实例
//System.out.println("proxyBeanMethods = true: user01 == user02: "+(user01 == user02)); // true
System.out.println("proxyBeanMethods = false: user01 == user02: "+(user01 == user02)); // false

User user = run.getBean("user01", User.class);
Pet tom = run.getBean("tom",Pet.class);
//System.out.println("proxyBeanMethods = true: 用户宠物是否为容器中的宠物:" + (user.getPet() == tom)); // true
System.out.println("proxyBeanMethods = false: 用户宠物是否为容器中的宠物:" + (user.getPet() == tom)); // false
}
}
  • 最佳实战
    • 配置类组件之间无依赖关系用 Lite 模式加速容器启动过程,减少判断
    • 配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用 Full 模式

2. @Bean、@Component、@Controller、@Service、@Repository

3. @ComponentScan、@Import

4. @Conditioal

img

  • MyConfig.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package site.shaoshao.boot.config;

import ch.qos.logback.core.db.DBHelper;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import site.shaoshao.boot.bean.Pet;
import site.shaoshao.boot.bean.User;

/**
* 1. 配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例
* 2. 配置类本身也是组件
* 3. 5.2后 proxyBeanMethods:代理bean的方法
* Full(proxyBeanMethods = true)
* Lite(proxyBeanMethods = false)
* 组件依赖
*
* 4. @Import({User.class, DBHelper.class})
* 给容器中自动创建出这两个类型的组件
*
*/
@ConditionalOnBean(name = "tom")
@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = true) //告诉Springboot这是一个配置类 == 配置文件
public class MyConfig {

/**
* 外部无论对配置文类中的这个组件注册方法调用多少次,获取到的都是之前注册到容器中的单实例对象
*/
@Bean //给容器中添加组件。以方法名
public User user01(){
User zhangsan = new User("zhangsan", 18);
//user组件依赖了pet组件
zhangsan.setPet(pet01());
return zhangsan;
}

@Bean("tom1")
public Pet pet01(){
return new Pet("tom");
}
}
  • MainApplication.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package site.shaoshao.boot;

import ch.qos.logback.core.db.DBHelper;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import site.shaoshao.boot.bean.Pet;
import site.shaoshao.boot.bean.User;
import site.shaoshao.boot.config.MyConfig;

/**
* 主程序类
*/
//@SpringBootApplication
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("site.shaoshao.boot")
public class MainApplication {
public static void main(String[] args) {
// 返回IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
// // 查看容器中组件
// String[] names = run.getBeanDefinitionNames();
// for (String name : names) {
// System.out.println(name);
// }
// // 从容器中获取组件
// Pet tom01 = run.getBean("tom", Pet.class);
// Pet tom02 = run.getBean("tom", Pet.class);
// System.out.println("组件单实例:"+(tom01==tom02));// true
//
// MyConfig bean = run.getBean(MyConfig.class);
// User user01 = bean.user01();
// User user02 = bean.user01();
// //如果@Configuration(proxyBeanMethods = true)代理对象调用方法。springboot总会检查这个组件是否在容器中注册
// //保持组件单实例
// //System.out.println("proxyBeanMethods = true: user01 == user02: "+(user01 == user02)); // true
// System.out.println("proxyBeanMethods = false: user01 == user02: "+(user01 == user02)); // false
//
// User user = run.getBean("user01", User.class);
// Pet tom = run.getBean("tom",Pet.class);
// //System.out.println("proxyBeanMethods = true: 用户宠物是否为容器中的宠物:" + (user.getPet() == tom)); // true
// System.out.println("proxyBeanMethods = false: 用户宠物是否为容器中的宠物:" + (user.getPet() == tom)); // false
//
// String[] beanNamesForType = run.getBeanNamesForType(User.class);
// System.out.println("===============");
// for (String s : beanNamesForType) {
// System.out.println(s);
// }
//
// DBHelper bean1 = run.getBean(DBHelper.class);
// System.out.println(bean1);
boolean tom = run.containsBean("tom");
System.out.println("容器中含有tom组件:" + tom);//false

boolean user01 = run.containsBean("user01");
System.out.println("容器中含有tom组件:" + user01);//false

boolean tom1 = run.containsBean("tom1");
System.out.println("容器中含有tom组件:" + tom1);
//@ConditionalOnBean(name = "tom") 标注在类上===>false
//@ConditionalOnBean(name = "tom") 标注在方法上===>true
}
}

2.2 原生配置文件引入

1. @ImportResource

  • beans.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="haha" class="site.shaoshao.boot.bean.User">
<property name="username" value="zhangsan"></property>
<property name="age" value="18"></property>
</bean>
<bean id="hehe" class="site.shaoshao.boot.bean.Pet">
<property name="name" value="tom"></property>
</bean>
</beans>
  • MyConfig.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package site.shaoshao.boot.config;

import ch.qos.logback.core.db.DBHelper;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
import site.shaoshao.boot.bean.Pet;
import site.shaoshao.boot.bean.User;

/**
* 1. 配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例
* 2. 配置类本身也是组件
* 3. 5.2后 proxyBeanMethods:代理bean的方法
* Full(proxyBeanMethods = true)
* Lite(proxyBeanMethods = false)
* 组件依赖
*
* 4. @Import({User.class, DBHelper.class})
* 给容器中自动创建出这两个类型的组件
*
*/
//@ConditionalOnBean(name = "tom")
//@Import({User.class, DBHelper.class})
@Configuration(proxyBeanMethods = false) //告诉Springboot这是一个配置类 == 配置文件
@ImportResource("classpath:beans.xml")
public class MyConfig {

/**
* 外部无论对配置文类中的这个组件注册方法调用多少次,获取到的都是之前注册到容器中的单实例对象
*/
@Bean //给容器中添加组件。以方法名
public User user01(){
User zhangsan = new User("zhangsan", 18);
//user组件依赖了pet组件
zhangsan.setPet(pet01());
return zhangsan;
}

@Bean("tom1")
public Pet pet01(){
return new Pet("tom");
}
}
  • MainApplication.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package site.shaoshao.boot;

import ch.qos.logback.core.db.DBHelper;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;

/**
* 主程序类
*/
//@SpringBootApplication
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("site.shaoshao.boot")
public class MainApplication {
public static void main(String[] args) {
// 返回IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

boolean haha = run.containsBean("haha");
System.out.println("容器中含有haha组件:" + haha);// true

boolean hehe = run.containsBean("hehe");
System.out.println("容器中含有hehe组件:" + hehe);// true
}
}

2.3 配置绑定

如何使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用;

1
2
3
4
5
6
7
8
9
10
11
12
13
public class getProperties {
public static void main(String[] args) throws FileNotFoundException, IOException {
Properties pps = new Properties();
pps.load(new FileInputStream("a.properties"));
Enumeration enum1 = pps.propertyNames();//得到配置文件的名字
while(enum1.hasMoreElements()) {
String strKey = (String) enum1.nextElement();
String strValue = pps.getProperty(strKey);
System.out.println(strKey + "=" + strValue);
//封装到JavaBean。
}
}
}

1. @Component + @ConfigurationProperties

  • application.properties
1
2
mycar.brand=BYD
mycar.price=100000
  • Car.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package site.shaoshao.boot.bean;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
* 只有在容器中的组件,才会拥有springboot提供的强大功能
*/
@Component
@ConfigurationProperties(prefix = "mycar")
public class Car {
private String brand;
private Integer price;

public Car() {
}

public Car(String brand, Integer price) {
this.brand = brand;
this.price = price;
}

public String getBrand() {
return brand;
}

public void setBrand(String brand) {
this.brand = brand;
}

public Integer getPrice() {
return price;
}

public void setPrice(Integer price) {
this.price = price;
}

@Override
public String toString() {
return "Car{" +
"brand='" + brand + '\'' +
", price=" + price +
'}';
}
}
  • Controller.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package site.shaoshao.boot.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import site.shaoshao.boot.bean.Car;

@RestController
public class HelloController {
@Autowired
Car car;

@RequestMapping("/hello")
public String handle01(){
return "hello spring boot!";
}

@RequestMapping("/car") //返回{"brand":"BYD","price":100000}
public Car car(){
return car;
}
}

2. @EnableConfigurationProperties + @ConfigurationProperties

  • 在 MyConfig.java 中 添加
1
2
@EnableConfigurationProperties(Car.class)   //省略 Car.java 中的 @Condition
//1. 开启Car的配置绑定功能 2. 把这个Car这个组件自动注册到容器中

3 自动配置原理入门

3.1 引导加载自动配置类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication{}


========================================

1. @SpringBootConfiguration

@Configuration:代表当前是一个配置类;

2. @ComponentScan

指定扫描哪些包,Spring注解;

3. @EnableAutoConfiguration

1
2
3
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {}
  • @AutoConfigurationPackage

    • 自动配置包
1
2
3
@Import({Registrar.class})	//给容器中导入一个Registrar组件
//将指定的包(MainApplication所在的包)下的所有组件导入进来
public @interface AutoConfigurationPackage {}
  • @Import({AutoConfigurationImportSelector.class})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
1. 利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件
2. 调用List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
获取到所有需要导入到容器中的配置类(组件)
3. 利用工厂加载 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader),得到所有的组件
4. 从 META-INF/spring.factories 位置加载一个文件
默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件
spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
文件里面写死了spring-boot一启动就要给容器中加载的所有配置类
spring-boot-autoconfigure-2.3.4.RELEASE.jar/META-INF/spring.factories
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
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.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
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.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
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.r2dbc.R2dbcDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
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.ElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
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.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
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.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration,\
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.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\
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.client.RestTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration

3.2 按需开启自动配置项

1
2
虽然我们127个场景的所有自动配置启动的时候默认全部加载。xxxxAutoConfiguration
按照条件装配规则(@Conditional),最终会按需配置。

3.3 修改默认配置

1
2
3
4
5
6
7
8
9
10
@Bean
@ConditionalOnBean(MultipartResolver.class) //容器中有这个类型组件
@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) //容器中没有这个名字 multipartResolver 的组件
public MultipartResolver multipartResolver(MultipartResolver resolver) {
//给@Bean标注的方法传入了对象参数,这个参数的值就会从容器中找。
//SpringMVC multipartResolver。防止有些用户配置的文件上传解析器不符合规范
// Detect if the user has created a MultipartResolver but named it incorrectly
return resolver;
}
给容器中加入了文件上传解析器;

SpringBoot默认会在底层配好所有的组件。但是如果用户自己配置了以用户的优先

1
2
3
4
@Bean
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
}

总结:

  • SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration

  • 每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件进行了绑定

  • 生效的配置类就会给容器中装配很多组件

  • 只要容器中有这些组件,相当于这些功能就有了

  • 定制化配置

    • 用户直接自己@Bean替换底层的组件
    • 用户去看这个组件是获取的配置文件什么值就去修改。

xxxxxAutoConfiguration —> 组件 —> xxxxProperties里面拿值 —-> application.properties

3.4 最佳实践

4 开发小技巧

4.1 Lombok

简化JavaBean开发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>


idea中搜索安装lombok插件
===============================简化JavaBean开发===================================
@Data //gatter、setter方法
@ToString //toString()方法
@AllArgsConstructor //全参构造器
@NoArgsConstructor //无参构造器
@EqualsAndHashCode //equalsAndHashCode()方法
public class User {

private String name;
private Integer age;
private Pet pet;

public User(String name,Integer age){
this.name = name;
this.age = age;
}
}



================================简化日志开发===================================
@Slf4j //日志
@RestController
public class HelloController {
@RequestMapping("/hello")
public String handle01(@RequestParam("name") String name){

log.info("请求进来了....");

return "Hello, Spring Boot 2!"+"你好:"+name;
}
}

4.2 dev-tools

1
2
3
4
5
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>

项目或者页面修改以后:Ctrl+F9;

4.3 Spring Initailizr(项目初始化向导)

1. 选择我们需要的开发场景

img

2. 自动依赖引入

img

3. 自动创建项目结构

img

4. 自动编写好主配置类

img
y_10)