1. 程式人生 > >idea springboot學習筆記

idea springboot學習筆記

一、Spring Boot 入門

1、Spring Boot 簡介

簡化Spring應用開發的一個框架;

整個Spring技術棧的一個大整合;

J2EE開發的一站式解決方案;

2、微服務

2014,martin fowler

微服務:架構風格(服務微化)

一個應用應該是一組小型服務;可以通過HTTP的方式進行互通;

單體應用:ALL IN ONE

微服務:每一個功能元素最終都是一個可獨立替換和獨立升級的軟體單元;

3、環境準備

環境約束

–jdk1.8:Spring Boot 推薦jdk1.7及以上;java version “1.8.0_112”

–maven3.x:maven 3.3以上版本;Apache Maven 3.3.9

–IntelliJIDEA2017:IntelliJ IDEA 2017.2.2 x64、STS

–SpringBoot 1.5.9.RELEASE:1.5.9;

統一環境;

1、MAVEN設定;

給maven 的settings.xml配置檔案的profiles標籤新增

1
2
3
4
5
6
7
8
9
10
11
12
<profile>
  <id>jdk-1.8</id>
  <activation>
    <activeByDefault>true</activeByDefault>
    <jdk>1.8</jdk>
  </activation>
  <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
  </properties>
</profile>

2、IDEA設定

整合maven進來;

idea設定

images/

4、Spring Boot HelloWorld

一個功能:

瀏覽器傳送hello請求,伺服器接受請求並處理,響應Hello World字串;

1、建立一個maven工程;(jar)

2、匯入spring boot相關的依賴

1
2
3
4
5
6
7
8
9
10
11
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

3、編寫一個主程式;啟動Spring Boot應用

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
 *  @SpringBootApplication 來標註一個主程式類,說明這是一個Spring Boot應用
 */
@SpringBootApplication
public class HelloWorldMainApplication {

    public static void main(String[] args) {

        // Spring應用啟動起來
        SpringApplication.run(HelloWorldMainApplication.class,args);
    }
}

4、編寫相關的Controller、Service

1
2
3
4
5
6
7
8
9
@Controller
public class HelloController {

    @ResponseBody
    @RequestMapping("/hello")
    public String hello(){
        return "Hello World!";
    }
}

5、執行主程式測試

6、簡化部署

1
2
3
4
5
6
7
8
9
<!-- 這個外掛,可以將應用打包成一個可執行的jar包;-->
   <build>
       <plugins>
           <plugin>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-maven-plugin</artifactId>
           </plugin>
       </plugins>
   </build>

將這個應用打成jar包,直接使用java -jar的命令進行執行;

5、Hello World探究

1、POM檔案

1、父專案

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
</parent>

他的父專案是
<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-dependencies</artifactId>
  <version>1.5.9.RELEASE</version>
  <relativePath>../../spring-boot-dependencies</relativePath>
</parent>
他來真正管理Spring Boot應用裡面的所有依賴版本;

Spring Boot的版本仲裁中心;

以後我們匯入依賴預設是不需要寫版本;(沒有在dependencies裡面管理的依賴自然需要宣告版本號)

2、啟動器

1
2
3
4
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

spring-boot-starter-==web==:

​ spring-boot-starter:spring-boot場景啟動器;幫我們匯入了web模組正常執行所依賴的元件;

Spring Boot將所有的功能場景都抽取出來,做成一個個的starters(啟動器),只需要在專案裡面引入這些starter相關場景的所有依賴都會匯入進來。要用什麼功能就匯入什麼場景的啟動器

2、主程式類,主入口類

1
2
3
4
5
6
7
8
9
10
11
12
/**
 *  @SpringBootApplication 來標註一個主程式類,說明這是一個Spring Boot應用
 */
@SpringBootApplication
public class HelloWorldMainApplication {

    public static void main(String[] args) {

        // Spring應用啟動起來
        SpringApplication.run(HelloWorldMainApplication.class,args);
    }
}

@SpringBootApplication: Spring Boot應用標註在某個類上說明這個類是SpringBoot的主配置類,SpringBoot就應該執行這個類的main方法來啟動SpringBoot應用;

1
2
3
4
5
6
7
8
9
10
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
      @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
      @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

@SpringBootConfiguration:Spring Boot的配置類;

​ 標註在某個類上,表示這是一個Spring Boot的配置類;

​ @Configuration:配置類上來標註這個註解;

​ 配置類 —– 配置檔案;配置類也是容器中的一個元件;@Component

@EnableAutoConfiguration:開啟自動配置功能;

​ 以前我們需要配置的東西,Spring Boot幫我們自動配置;@EnableAutoConfiguration告訴SpringBoot開啟自動配置功能;這樣自動配置才能生效;

1
2
3
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

​ @AutoConfigurationPackage:自動配置包

​ @Import(AutoConfigurationPackages.Registrar.class):

​ Spring的底層註解@Import,給容器中匯入一個元件;匯入的元件由AutoConfigurationPackages.Registrar.class;

==將主配置類(@SpringBootApplication標註的類)的所在包及下面所有子包裡面的所有元件掃描到Spring容器;==

​ @Import(EnableAutoConfigurationImportSelector.class);

​ 給容器中匯入元件?

​ EnableAutoConfigurationImportSelector:匯入哪些元件的選擇器;

​ 將所有需要匯入的元件以全類名的方式返回;這些元件就會被新增到容器中;

​ 會給容器中匯入非常多的自動配置類(xxxAutoConfiguration);就是給容器中匯入這個場景需要的所有元件,並配置好這些元件;自動配置類

有了自動配置類,免去了我們手動編寫配置注入功能元件等的工作;

​ SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader);

==Spring Boot在啟動的時候從類路徑下的META-INF/spring.factories中獲取EnableAutoConfiguration指定的值,將這些值作為自動配置類匯入到容器中,自動配置類就生效,幫我們進行自動配置工作;==以前我們需要自己配置的東西,自動配置類都幫我們;

J2EE的整體整合解決方案和自動配置都在spring-boot-autoconfigure-1.5.9.RELEASE.jar;

==Spring註解版(穀粒學院)==

6、使用Spring Initializer快速建立Spring Boot專案

1、IDEA:使用 Spring Initializer快速建立專案

IDE都支援使用Spring的專案建立嚮導快速建立一個Spring Boot專案;

選擇我們需要的模組;嚮導會聯網建立Spring Boot專案;

預設生成的Spring Boot專案;

  • 主程式已經生成好了,我們只需要我們自己的邏輯
  • resources資料夾中目錄結構
    • static:儲存所有的靜態資源; js css images;
    • templates:儲存所有的模板頁面;(Spring Boot預設jar包使用嵌入式的Tomcat,預設不支援JSP頁面);可以使用模板引擎(freemarker、thymeleaf);
    • application.properties:Spring Boot應用的配置檔案;可以修改一些預設設定;

2、STS使用 Spring Starter Project快速建立專案

二、配置檔案

1、配置檔案

SpringBoot使用一個全域性的配置檔案,配置檔名是固定的;

•application.properties

•application.yml

配置檔案的作用:修改SpringBoot自動配置的預設值;SpringBoot在底層都給我們自動配置好;

YAML(YAML Ain’t Markup Language)

​ YAML A Markup Language:是一個標記語言

​ YAML isn’t Markup Language:不是一個標記語言;

標記語言:

​ 以前的配置檔案;大多都使用的是 xxxx.xml檔案;

​ YAML:以資料為中心,比json、xml等更適合做配置檔案;

​ YAML:配置例子

1
2
server:
  port: 8081

​ XML:

1
2
3
<server>
  <port>8081</port>
</server>

2、YAML語法:

1、基本語法

k:(空格)v:表示一對鍵值對(空格必須有);

空格的縮排來控制層級關係;只要是左對齊的一列資料,都是同一個層級的

1
2
3
server:
    port: 8081
    path: /hello

屬性和值也是大小寫敏感;

2、值的寫法

字面量:普通的值(數字,字串,布林)

​ k: v:字面直接來寫;

​ 字串預設不用加上單引號或者雙引號;

​ “”:雙引號;不會轉義字串裡面的特殊字元;特殊字元會作為本身想表示的意思

​ name: “zhangsan \n lisi”:輸出;zhangsan 換行 lisi

​ ‘’:單引號;會轉義特殊字元,特殊字元最終只是一個普通的字串資料

​ name: ‘zhangsan \n lisi’:輸出;zhangsan \n lisi

物件、Map(屬性和值)(鍵值對):

​ k: v:在下一行來寫物件的屬性和值的關係;注意縮排

​ 物件還是k: v的方式

1
2
3
friends:
    lastName: zhangsan
    age: 20

行內寫法:

1
friends: {lastName: zhangsan,age: 18}

陣列(List、Set):

用- 值表示陣列中的一個元素

1
2
3
4
pets:
 - cat
 - dog
 - pig

行內寫法

1
pets: [cat,dog,pig]

3、配置檔案值注入

配置檔案

1
2
3
4
5
6
7
8
9
10
11
12
person:
    lastName: hello
    age: 18
    boss: false
    birth: 2017/12/12
    maps: {k1: v1,k2: 12}
    lists:
      - lisi
      - zhaoliu
    dog:
      name: 小狗
      age: 12

javaBean:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
 * 將配置檔案中配置的每一個屬性的值,對映到這個元件中
 * @ConfigurationProperties:告訴SpringBoot將本類中的所有屬性和配置檔案中相關的配置進行繫結;
 *      prefix = "person":配置檔案中哪個下面的所有屬性進行一一對映
 *
 * 只有這個元件是容器中的元件,才能容器提供的@ConfigurationProperties功能;
 *
 */
@Component
@ConfigurationProperties(prefix = "person")
public class Person {

    private String lastName;
    private Integer age;
    private Boolean boss;
    private Date birth;

    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog;

我們可以匯入配置檔案處理器,以後編寫配置就有提示了

1
2
3
4
5
6
<!--匯入配置檔案處理器,配置檔案進行繫結就會有提示-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-configuration-processor</artifactId>
      <optional>true</optional>
    </dependency>

1、properties配置檔案在idea中預設utf-8可能會亂碼

調整

idea配置亂碼

2、@Value獲取值和@ConfigurationProperties獲取值比較

@ConfigurationProperties @Value
功能 批量注入配置檔案中的屬性 一個個指定
鬆散繫結(鬆散語法) 支援 不支援
SpEL 不支援 支援
JSR303資料校驗 支援 不支援
複雜型別封裝 支援 不支援

配置檔案yml還是properties他們都能獲取到值;

如果說,我們只是在某個業務邏輯中需要獲取一下配置檔案中的某項值,使用@Value;

如果說,我們專門編寫了一個javaBean來和配置檔案進行對映,我們就直接使用@ConfigurationProperties;

3、配置檔案注入值資料校驗

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {

    /**
     * <bean class="Person">
     *      <property name="lastName" value="字面量/${key}從環境變數、配置檔案中獲取值/#{SpEL}"></property>
     * <bean/>
     */

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

    private Date birth;
    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog;

4、@PropertySource&@ImportResource&@Bean

@PropertySource:載入指定的配置檔案;

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
/**
 * 將配置檔案中配置的每一個屬性的值,對映到這個元件中
 * @ConfigurationProperties:告訴SpringBoot將本類中的所有屬性和配置檔案中相關的配置進行繫結;
 *      prefix = "person":配置檔案中哪個下面的所有屬性進行一一對映
 *
 * 只有這個元件是容器中的元件,才能容器提供的@ConfigurationProperties功能;
 *  @ConfigurationProperties(prefix = "person")預設從全域性配置檔案中獲取值;
 *
 */
@PropertySource(value = {"classpath:person.properties"})
@Component
@ConfigurationProperties(prefix = "person")
//@Validated
public class Person {

    /**
     * <bean class="Person">
     *      <property name="lastName" value="字面量/${key}從環境變數、配置檔案中獲取值/#{SpEL}"></property>
     * <bean/>
     */

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

@ImportResource:匯入Spring的配置檔案,讓配置檔案裡面的內容生效;

Spring Boot裡面沒有Spring的配置檔案,我們自己編寫的配置檔案,也不能自動識別;

想讓Spring的配置檔案生效,載入進來;@ImportResource標註在一個配置類上

1
2
@ImportResource(locations = {"classpath:beans.xml"})
匯入Spring的配置檔案讓其生效

不來編寫Spring的配置檔案

1
2
3
4
5
6
7
8
<?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="helloService" class="com.atguigu.springboot.service.HelloService"></bean>
</beans>

SpringBoot推薦給容器中新增元件的方式;推薦使用全註解的方式

1、配置類@Configuration——>Spring配置檔案

2、使用@Bean給容器中新增元件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
 * @Configuration:指明當前類是一個配置類;就是來替代之前的Spring配置檔案
 *
 * 在配置檔案中用<bean><bean/>標籤新增元件
 *
 */
@Configuration
public class MyAppConfig {

    //將方法的返回值新增到容器中;容器中這個元件預設的id就是方法名
    @Bean
    public HelloService helloService02(){
        System.out.println("配置類@Bean給容器中新增元件了...");
        return new HelloService();
    }
}

##4、配置檔案佔位符

1、隨機數

1
2
${random.value}、${random.int}、${random.long}
${random.int(10)}、${random.int[1024,65536]}

2、佔位符獲取之前配置的值,如果沒有可以是用:指定預設值

1
2
3
4
5
6
7
8
9
person.last-name=張三${random.uuid}
person.age=${random.int}
person.birth=2017/12/15
person.boss=false
person.maps.k1=v1
person.maps.k2=14
person.lists=a,b,c
person.dog.name=${person.hello:hello}_dog
person.dog.age=15

5、Profile

1、多Profile檔案

我們在主配置檔案編寫的時候,檔名可以是 application-{profile}.properties/yml

預設使用application.properties的配置;

2、yml支援多文件塊方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server:
  port: 8081
spring:
  profiles:
    active: prod

---
server:
  port: 8083
spring:
  profiles: dev


---

server:
  port: 8084
spring:
  profiles: prod  #指定屬於哪個環境

3、啟用指定profile

​ 1、在配置檔案中指定 spring.profiles.active=dev

​ 2、命令列:

​ java -jar spring-boot-02-config-0.0.1-SNAPSHOT.jar –spring.profiles.active=dev;

​ 可以直接在測試的時候,配置傳入命令列引數

​ 3、虛擬機器引數;

​ -Dspring.profiles.active=dev

6、配置檔案載入位置

springboot 啟動會掃描以下位置的application.properties或者application.yml檔案作為Spring boot的預設配置檔案

–file:./config/

–file:./

–classpath:/config/

–classpath:/

優先順序由高到底,高優先順序的配置會覆蓋低優先順序的配置;

SpringBoot會從這四個位置全部載入主配置檔案;互補配置

==我們還可以通過spring.config.location來改變預設的配置檔案位置==

專案打包好以後,我們可以使用命令列引數的形式,啟動專案的時候來指定配置檔案的新位置;指定配置檔案和預設載入的這些配置檔案共同起作用形成互補配置;

java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar –spring.config.location=G:/application.properties

7、外部配置載入順序

==SpringBoot也可以從以下位置載入配置; 優先順序從高到低;高優先順序的配置覆蓋低優先順序的配置,所有的配置會形成互補配置==

1.命令列引數

所有的配置都可以在命令列上進行指定

java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar –server.port=8087 –server.servlet.context-path=/abc

多個配置用空格分開; –配置項=值

2.來自java:comp/env的JNDI屬性

3.Java系統屬性(System.getProperties())

4.作業系統環境變數

5.RandomValuePropertySource配置的random.*屬性值

==由jar包外向jar包內進行尋找;==

==優先載入帶profile==

6.jar包外部的application-{profile}.properties或application.yml(帶spring.profile)配置檔案

7.jar包內部的application-{profile}.properties或application.yml(帶spring.profile)配置檔案

==再來載入不帶profile==

8.jar包外部的application.properties或application.yml(不帶spring.profile)配置檔案

9.jar包內部的application.properties或application.yml(不帶spring.profile)配置檔案

[email protected]註解類上的@PropertySource

11.通過SpringApplication.setDefaultProperties指定的預設屬性

所有支援的配置載入來源;

8、自動配置原理

配置檔案到底能寫什麼?怎麼寫?自動配置原理;

1、自動配置原理:

1)、SpringBoot啟動的時候載入主配置類,開啟了自動配置功能 [email protected]==

2)、@EnableAutoConfiguration 作用:

  • 利用EnableAutoConfigurationImportSelector給容器中匯入一些元件?
  • 可以檢視selectImports()方法的內容;

  • List configurations = getCandidateConfigurations(annotationMetadata, attributes);獲取候選的配置

    • 1
      2
      3
      4
      
      SpringFactoriesLoader.loadFactoryNames()
      掃描所有jar包類路徑下  META-INF/spring.factories
      把掃描到的這些檔案的內容包裝成properties物件
      從properties中獲取到EnableAutoConfiguration.class類(類名)對應的值,然後把他們新增在容器中
      

==將 類路徑下 META-INF/spring.factories 裡面配置的所有EnableAutoConfiguration的值加入到了容器中;==

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
# 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.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

每一個這樣的 xxxAutoConfiguration類都是容器中的一個元件,都加入到容器中;用他們來做自動配置;

3)、每一個自動配置類進行自動配置功能;

4)、以HttpEncodingAutoConfiguration(Http編碼自動配置)為例解釋自動配置原理;

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
@Configuration   //表示這是一個配置類,以前編寫的配置檔案一樣,也可以給容器中新增元件
@EnableConfigurationProperties(HttpEncodingProperties.class)  //啟動指定類的ConfigurationProperties功能;將配置檔案中對應的值和HttpEncodingProperties繫結起來;並把HttpEncodingProperties加入到ioc容器中

@ConditionalOnWebApplication //Spring底層@Conditional註解(Spring註解版),根據不同的條件,如果滿足指定的條件,整個配置類裡面的配置就會生效;    判斷當前應用是否是web應用,如果是,當前配置類生效

@ConditionalOnClass(CharacterEncodingFilter.class)  //判斷當前專案有沒有這個類CharacterEncodingFilter;SpringMVC中進行亂碼解決的過濾器;

@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)  //判斷配置檔案中是否存在某個配置  spring.http.encoding.enabled;如果不存在,判斷也是成立的
//即使我們配置檔案中不配置pring.http.encoding.enabled=true,也是預設生效的;
public class HttpEncodingAutoConfiguration {
  
    //他已經和SpringBoot的配置檔案映射了
    private final HttpEncodingProperties properties;
  
   //只有一個有參構造器的情況下,引數的值就會從容器中拿
    public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
    this.properties = properties;
  }
  
    @Bean   //給容器中新增一個元件,這個元件的某些值需要從properties中獲取
  @ConditionalOnMissingBean(CharacterEncodingFilter.class) //判斷容器沒有這個元件?
  public CharacterEncodingFilter characterEncodingFilter() {
    CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
    filter.setEncoding(this.properties.getCharset().name());
    filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
    filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
    return filter;
  }

根據當前不同的條件判斷,決定這個配置類是否生效?

一但這個配置類生效;這個配置類就會給容器中新增各種元件;這些元件的屬性是從對應的properties類中獲取的,這些類裡面的每一個屬性又是和配置檔案繫結的;

5)、所有在配置檔案中能配置的屬性都是在xxxxProperties類中封裝者‘;配置檔案能配置什麼就可以參照某個功能對應的這個屬性類

1
2
3
4
@ConfigurationProperties(prefix = "spring.http.encoding")  //從配置檔案中獲取指定的值和bean的屬性進行繫結
public class HttpEncodingProperties {

   public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

精髓:

​ 1)、SpringBoot啟動會載入大量的自動配置類

​ 2)、我們看我們需要的功能有沒有SpringBoot預設寫好的自動配置類;

​ 3)、我們再來看這個自動配置類中到底配置了哪些元件;(只要我們要用的元件有,我們就不需要再來配置了)

​ 4)、給容器中自動配置類新增元件的時候,會從properties類中獲取某些屬性。我們就可以在配置檔案中指定這些屬性的值;

xxxxAutoConfigurartion:自動配置類;

給容器中新增元件

xxxxProperties:封裝配置檔案中相關屬性;

2、細節

1、@Conditional派生註解(Spring註解版原生的@Conditional作用)

作用:必須是@Conditional指定的條件成立,才給容器中新增元件,配置配裡面的所有內容才生效;

@Conditional擴充套件註解 作用(判斷是否滿足當前指定條件)
@ConditionalOnJava 系統的java版本是否符合要求
@ConditionalOnBean 容器中存在指定Bean;
@ConditionalOnMissingBean 容器中不存在指定Bean;
@ConditionalOnExpression 滿足SpEL表示式指定
@ConditionalOnClass 系統中有指定的類
@ConditionalOnMissingClass 系統中沒有指定的類
@ConditionalOnSingleCandidate 容器中只有一個指定的Bean,或者這個Bean是首選Bean
@ConditionalOnProperty 系統中指定的屬性是否有指定的值
@ConditionalOnResource 類路徑下是否存在指定資原始檔
@ConditionalOnWebApplication 當前是web環境
@ConditionalOnNotWebApplication 當前不是web環境
@ConditionalOnJndi JNDI存在指定項

自動配置類必須在一定的條件下才能生效;

我們怎麼知道哪些自動配置類生效;

==我們可以通過啟用 debug=true屬性;來讓控制檯列印自動配置報告==,這樣我們就可以很方便的知道哪些自動配置類生效;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
=========================
AUTO-CONFIGURATION REPORT
=========================


Positive matches:(自動配置類啟用的)
-----------------

   DispatcherServletAutoConfiguration matched:
      - @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
      - @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition)
        
    
Negative matches:(沒有啟動,沒有匹配成功的自動配置類)
-----------------

   ActiveMQAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition)

   AopAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required classes 'org.aspectj.lang.annotation.Aspect', 'org.aspectj.lang.reflect.Advice' (OnClassCondition)

三、日誌

1、日誌框架

小張;開發一個大型系統;

​ 1、System.out.println(“”);將關鍵資料列印在控制檯;去掉?寫在一個檔案?

​ 2、框架來記錄系統的一些執行時資訊;日誌框架 ; zhanglogging.jar;

​ 3、高大上的幾個功能?非同步模式?自動歸檔?xxxx? zhanglogging-good.jar?

​ 4、將以前框架卸下來?換上新的框架,重新修改之前相關的API;zhanglogging-prefect.jar;

​ 5、JDBC—資料庫驅動;

​ 寫了一個統一的介面層;日誌門面(日誌的一個抽象層);logging-abstract.jar;

​ 給專案中匯入具體的日誌實現就行了;我們之前的日誌框架都是實現的抽象層;

市面上的日誌框架;

JUL、JCL、Jboss-logging、logback、log4j、log4j2、slf4j….

日誌門面 (日誌的抽象層) 日誌實現
JCL(Jakarta Commons Logging)SLF4j(Simple Logging Facade for Java) jboss-logging Log4j JUL(java.util.logging) Log4j2Logback

左邊選一個門面(抽象層)、右邊來選一個實現;

日誌門面: SLF4J;

日誌實現:Logback;

SpringBoot:底層是Spring框架,Spring框架預設是用JCL;‘

​ ==SpringBoot選用 SLF4j和logback;==

2、SLF4j使用

以後開發的時候,日誌記錄方法的呼叫,不應該來直接呼叫日誌的實現類,而是呼叫日誌抽象層裡面的方法;

給系統裡面匯入slf4j的jar和 logback的實現jar

1
2
3
4
5
6
7
8
9
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {
  public static void main(String[] args) {
    Logger logger = LoggerFactory.getLogger(HelloWorld.class);
    logger.info("Hello World");
  }
}

圖示;

images/concrete-bindings.png

每一個日誌的實現框架都有自己的配置檔案。使用slf4j以後,配置檔案還是做成日誌實現框架自己本身的配置檔案;

2、遺留問題

a(slf4j+logback): Spring(commons-logging)、Hibernate(jboss-logging)、MyBatis、xxxx

統一日誌記錄,即使是別的框架和我一起統一使用slf4j進行輸出?

如何讓系統中所有的日誌都統一到slf4j;

==1、將系統中其他日誌框架先排除出去;==

==2、用中間包來替換原有的日誌框架;==

==3、我們匯入slf4j其他的實現==

3、SpringBoot日誌關係

1
2
3
4
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
</dependency>

SpringBoot使用它來做日誌功能;

1
2
3
4
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-logging</artifactId>
  </dependency>

底層依賴關係

總結:

​ 1)、SpringBoot底層也是使用slf4j+logback的方式進行日誌記錄

​ 2)、SpringBoot也把其他的日誌都替換成了slf4j;

​ 3)、中間替換包?

1
2
3
4
5
6
@SuppressWarnings("rawtypes")
public abstract class LogFactory {

    static String UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J = "http://www.slf4j.org/codes.html#unsupported_operation_in_jcl_over_slf4j";

    static LogFactory logFactory = new SLF4JLogFactory();

​ 4)、如果我們要引入其他框架?一定要把這個框架的預設日誌依賴移除掉?

​ Spring框架用的是commons-logging;

1
2
3
4
5
6
7
8
9
10
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <exclusions>
    <exclusion>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
    </exclusion>
  </exclusions>
</dependency>

==SpringBoot能自動適配所有的日誌,而且底層使用slf4j+logback的方式記錄日誌,引入其他框架的時候,只需要把這個框架依賴的日誌框架排除掉即可;==

4、日誌使用;

1、預設配置

SpringBoot預設幫我們配置好了日誌;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//記錄器
Logger logger = LoggerFactory.getLogger(getClass());
@Test
public void contextLoads() {
  //System.out.println();

  //日誌的級別;
  //由低到高   trace<debug<info<warn<error
  //可以調整輸出的日誌級別;日誌就只會在這個級別以以後的高級別生效
  logger.trace("這是trace日誌...");
  logger.debug("這是debug日誌...");
  //SpringBoot預設給我們使用的是info級別的,沒有指定級別的就用SpringBoot預設規定的級別;root級別
  logger.info("這是info日誌...");
  logger.warn("這是warn日誌...");
  logger.error("這是error日誌...");


}
日誌輸出格式:
%d表示日期時間,
%thread表示執行緒名,
%-5level:級別從左顯示5個字元寬度
%logger{50} 表示logger名字最長50個字元,否則按照句點分割。 
%msg:日誌訊息,
%n是換行符
-->
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n

SpringBoot修改日誌的預設配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
logging.level.com.atguigu=trace


#logging.path=
# 不指定路徑在當前專案下生成springboot.log日誌
# 可以指定完整的路徑;
#logging.file=G:/springboot.log

# 在當前磁碟的根路徑下建立spring資料夾和裡面的log資料夾;使用 spring.log 作為預設檔案
logging.path=/spring/log

#  在控制檯輸出的日誌的格式
logging.pattern.console=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n
# 指定檔案中日誌輸出的格式
logging.pattern.file=%d{yyyy-MM-dd} === [%thread] === %-5level === %logger{50} ==== %msg%n
logging.file logging.path Example Description
(none) (none) 只在控制檯輸出
指定檔名 (none) my.log 輸出日誌到my.log檔案
(none) 指定目錄 /var/log 輸出到指定目錄的 spring.log 檔案中

2、指定配置

給類路徑下放上每個日誌框架自己的配置檔案即可;SpringBoot就不使用他預設配置的了

Logging System Customization
Logback logback-spring.xmllogback-spring.groovylogback.xml or logback.groovy
Log4j2 log4j2-spring.xml or log4j2.xml
JDK (Java Util Logging) logging.properties

logback.xml:直接就被日誌框架識別了;

logback-spring.xml:日誌框架就不直接載入日誌的配置項,由SpringBoot解析日誌配置,可以使用SpringBoot的高階Profile功能

1
2
3
4
<springProfile name="staging">
    <!-- configuration to be enabled when the "staging" profile is active -->
    可以指定某段配置只在某個環境下生效
</springProfile>

如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <!--
        日誌輸出格式:
      %d表示日期時間,
      %thread表示執行緒名,
      %-5level:級別從左顯示5個字元寬度
      %logger{50} 表示logger名字最長50個字元,否則按照句點分割。 
      %msg:日誌訊息,
      %n是換行符
        -->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <springProfile name="dev">
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n</pattern>
            </springProfile>
            <springProfile name="!dev">
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ==== [%thread] ==== %-5level %logger{50} - %msg%n</pattern>
            </springProfile>
        </layout>
    </appender>

如果使用logback.xml作為日誌配置檔案,還要使用profile功能,會有以下錯誤

no applicable action for [springProfile]

5、切換日誌框架

可以按照slf4j的日誌適配圖,進行相關的切換;

slf4j+log4j的方式;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <exclusions>
    <exclusion>
      <artifactId>logback-classic</artifactId>
      <groupId>ch.qos.logback</groupId>
    </exclusion>
    <exclusion>
      <artifactId>log4j-over-slf4j</artifactId>
      <groupId>org.slf4j</groupId>
    </exclusion>
  </exclusions>
</dependency>

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
</dependency>

切換為log4j2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
   <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>spring-boot-starter-logging</artifactId>
                    <groupId>org.springframework.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

四、Web開發

1、簡介

使用SpringBoot;

1)、建立SpringBoot應用,選中我們需要的模組;

2)、SpringBoot已經預設將這些場景配置好了,只需要在配置檔案中指定少量配置就可以執行起來

3)、自己編寫業務程式碼;

自動配置原理?

這個場景SpringBoot幫我們配置了什麼?能不能修改?能修改哪些配置?能不能擴充套件?xxx

1
2
xxxxAutoConfiguration:幫我們給容器中自動配置元件;
xxxxProperties:配置類來封裝配置檔案的內容;

2、SpringBoot對靜態資源的對映規則;

1
2
3
@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties implements ResourceLoaderAware {
  //可以設定和靜態資源有關的引數,快取時間等
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
WebMvcAuotConfiguration:
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    if (!this.resourceProperties.isAddMappings()) {
      logger.debug("Default resource handling disabled");
      return;
    }
    Integer cachePeriod = this.resourceProperties.getCachePeriod();
    if (!registry.hasMappingForPattern("/webjars/**")) {
      customizeResourceHandlerRegistration(
          registry.addResourceHandler("/webjars/**")
              .addResourceLocations(
                  "classpath:/META-INF/resources/webjars/")
          .setCachePeriod(cachePeriod));
    }
    String staticPathPattern = this.mvcProperties.getStaticPathPattern();
          //靜態資原始檔夾對映
    if (!registry.hasMappingForPattern(staticPathPattern)) {
      customizeResourceHandlerRegistration(
          registry.addResourceHandler(staticPathPattern)
              .addResourceLocations(
                  this.resourceProperties.getStaticLocations())
          .setCachePeriod(cachePeriod));
    }
  }

      //配置歡迎頁對映
  @Bean
  public WelcomePageHandlerMapping welcomePageHandlerMapping(
      ResourceProperties resourceProperties) {
    return new WelcomePageHandlerMapping(resourceProperties.getWelcomePage(),
        this.mvcProperties.getStaticPathPattern());
  }

     //配置喜歡的圖示
  @Configuration
  @ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)
  public static class FaviconConfiguration {

    private final ResourceProperties resourceProperties;

    public FaviconConfiguration(ResourceProperties resourceProperties) {
      this.resourceProperties = resourceProperties;
    }

    @Bean
    public SimpleUrlHandlerMapping faviconHandlerMapping() {
      SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
      mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
              //所有  **/favicon.ico 
      mapping.setUrlMap(Collections.singletonMap("**/favicon.ico",
          faviconRequestHandler()));
      return mapping;
    }

    @Bean
    public ResourceHttpRequestHandler faviconRequestHandler() {
      ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
      requestHandler
          .setLocations(this.resourceProperties.getFaviconLocations());
      return requestHandler;
    }

  }

==1)、所有 /webjars/** ,都去 classpath:/META-INF/resources/webjars/ 找資源;==

​ webjars:以jar包的方式引入靜態資源;

localhost:8080/webjars/jquery/3.3.1/jquery.js

1
2
3
4
5
6
<!--引入jquery-webjar-->在訪問的時候只需要寫webjars下面資源的名稱即可
    <dependency>
      <groupId>org.webjars</groupId>
      <artifactId>jquery</artifactId>
      <version>3.3.1</version>
    </dependency>

==2)、”/**” 訪問當前專案的任何資源,都去(靜態資源的資料夾)找對映==

1
2
3
4
5
"classpath:/META-INF/resources/", 
"classpath:/resources/",
"classpath:/static/", 
"classpath:/public/" 
"/":當前專案的根路徑

localhost:8080/abc === 去靜態資原始檔夾裡面找abc

==3)、歡迎頁; 靜態資原始檔夾下的所有index.html頁面;被”/**”對映;==

​ localhost:8080/ 找index頁面

==4)、所有的 **/favicon.ico 都是在靜態資原始檔下找;==

3、模板引擎

JSP、Velocity、Freemarker、Thymeleaf

SpringBoot推薦的Thymeleaf;

語法更簡單,功能更強大;

1、引入thymeleaf;

1
2
3
4
5
6
7
8
9
10
11
12
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-thymeleaf</artifactId>
            2.1.6
    </dependency>
切換thymeleaf版本
<properties>
    <thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
    <!-- 佈局功能的支援程式  thymeleaf3主程式  layout2以上版本 -->
    <!-- thymeleaf2   layout1-->
    <thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
  </properties>

2、Thymeleaf使用

1
2
3
4
5
6
7
8
9
10
11
@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {

  private static final Charset DEFAULT_ENCODING = Charset.forName("UTF-8");

  private static final MimeType DEFAULT_CONTENT_TYPE = MimeType.valueOf("text/html");

  public static final String DEFAULT_PREFIX = "classpath:/templates/";

  public static final String DEFAULT_SUFFIX = ".html";
    //

只要我們把HTML頁面放在classpath:/templates/,thymeleaf就能自動渲染;

使用:

1、匯入thymeleaf的名稱空間

1
<html lang="en" xmlns:th="http://www.thymeleaf.org">

2、使用thymeleaf語法;

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <