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進來;
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可能會亂碼
調整
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"); } } |
圖示;
每一個日誌的實現框架都有自己的配置檔案。使用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.xml , logback-spring.groovy , logback.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> < |