spring boot與thymeleaf使用
1. spring boot工作原理
1.1 spring架構優缺點分析
- 優點
Spring是Java企業版(Java Enterprise Edition,JEE,也稱J2EE)的輕量級代替品。無需開發重量級的Enterprise JavaBean(EJB),Spring為企業級Java開發提供了一種相對簡單的方法,通過依賴注入和面向切面程式設計,用簡單的Java對象(Plain Old Java Object,POJO)實作了EJB的功能
- 缺點
Spring的元件代碼是輕量級的,但它的配置卻是重量級的。一開始,Spring用XML配置,而且是很多XML配置。Spring 2.5引入了基于注解的元件掃描,這消除了大量針對應用程式自身元件的顯式XML配置。Spring 3.0引入了基于Java的配置,這是一種類型安全的可重構配置方式,可以代替XML。
所有這些配置都代表了開發時的損耗。因為在思考Spring特性配置和解決業務問題之間需要進行思維切換,是以編寫配置擠占了編寫應用程式邏輯的時間。和所有架構一樣,Spring實用,但與此同時它要求的回報也不少。
1.2 spring boot概述
1.2.1 spring boot 特點
- 為基于Spring的開發提供更快的入門體驗
- 開箱即用,沒有代碼生成,也無需XML配置。同時也可以修改預設值來滿足特定的需求
- 提供了一些大型項目中常見的非功能性特性,如嵌入式伺服器、安全、名額,健康檢測、外部配置等
- SpringBoot不是對Spring功能上的增強,而是提供了一種快速使用Spring的方式
- 讓項目的環境搭建變的異常簡單
1.2.2 spring boot的核心功能
- 起步依賴
起步依賴本質上是一個Maven項目對象模型(Project Object Model,POM),定義了對其他庫的傳遞依賴,這些東西加在一起即支援某項功能。
簡單的說,起步依賴就是将具備某種功能的坐标打包到一起,并提供一些預設的功能。
- 自動配置
Spring Boot的自動配置是一個運作時(更準确地說,是應用程式啟動時)的過程,考慮了衆多因素,才決定Spring配置應該用哪個,不該用哪個。該過程是Spring自動完成的。
1.3 spring boot起步依賴
1.3.1 工程建立
1.3.2 建立控制層
1.3.3 測試
2. 快速入門解析
2.1 SpringBoot代碼解析
- @SpringBootApplication:标注SpringBoot的啟動類,該注解具備多種功能(後面詳細剖析)
- SpringApplication.run(MySpringBootApplication.class) 代表運作SpringBoot的啟動類,參數為SpringBoot啟動類的位元組碼對象
2.2 SpringBoot工程熱部署
我們在開發中反複修改類、頁面等資源,每次修改後都是需要重新啟動才生效,這樣每次啟動都很麻煩,浪費了大量的時間,我們可以在修改代碼後不重新開機就能生效,在 pom.xml 中添加如下配置就可以實作這樣的功能,我們稱之為熱部署。
2.2.1 添加坐标
<!--熱部署配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<!-- 不能被其它子產品繼承,如果多個子子產品可以去掉 不必須-->
<optional>true</optional>
<!-- 隻在運作時,起作用,不會打到war包-->
<scope>runtime</scope>
</dependency>
2.2.2 配置插件參數
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!--fork : 如果沒有該項配置,肯呢個devtools不會起作用,即應用不會restart 這個要手動加進去 -->
<fork>true</fork>
</configuration>
</plugin>
注意:IDEA進行SpringBoot熱部署失敗原因
出現這種情況,并不是熱部署配置問題,其根本原因是因為Intellij IEDA預設情況下不會自動編譯,需要對IDEA進行自動編譯的設定,如下:
[外鍊圖檔轉存失敗(img-gMbJpad9-1567082938170)(md_images\19.png)]
然後 Shift+Ctrl+Alt+/,選擇Registry
[外鍊圖檔轉存失敗(img-kO1rtqr2-1567082938172)(md_images\20.png)]
2.3 起步依賴原理分析
2.3.1 分析spring-boot-starter-parent
按住Ctrl點選pom.xml中的spring-boot-starter-parent,跳轉到了spring-boot-starter-parent的pom.xml,xml配置如下(隻摘抄了部分重點配置):
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
按住Ctrl點選pom.xml中的spring-boot-starter-dependencies,跳轉到了spring-boot-starter-dependencies的pom.xml,xml配置如下(隻摘抄了部分重點配置):
<properties>
<activemq.version>5.15.3</activemq.version>
<antlr2.version>2.7.7</antlr2.version>
<appengine-sdk.version>1.9.63</appengine-sdk.version>
<artemis.version>2.4.0</artemis.version>
<aspectj.version>1.8.13</aspectj.version>
<assertj.version>3.9.1</assertj.version>
<atomikos.version>4.0.6</atomikos.version>
<bitronix.version>2.1.4</bitronix.version>
<build-helper-maven-plugin.version>3.0.0</build-helper-maven-plugin.version>
<byte-buddy.version>1.7.11</byte-buddy.version>
... ... ...
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>
... ... ...
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
</plugin>
<plugin>
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<version>${jooq.version}</version>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.0.1.RELEASE</version>
</plugin>
... ... ...
</plugins>
</pluginManagement>
</build>
從上面的spring-boot-starter-dependencies的pom.xml中我們可以發現,一部分坐标的版本、依賴管理、插件管理已經定義好,是以我們的SpringBoot工程繼承spring-boot-starter-parent後已經具備版本鎖定等配置了。是以起步依賴的作用就是進行依賴的傳遞。
2.3.2 分析spring-boot-starter-web
按住Ctrl點選pom.xml中的spring-boot-starter-web,跳轉到了spring-boot-starter-web的pom.xml,xml配置如下(隻摘抄了部分重點配置):
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starters</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.0.1.RELEASE</version>
<name>Spring Boot Web Starter</name>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.0.1.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
<version>2.0.1.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.0.1.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.9.Final</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.5.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.5.RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
從上面的spring-boot-starter-web的pom.xml中我們可以發現,spring-boot-starter-web就是将web開發要使用的spring-web、spring-webmvc等坐标進行了“打包”,這樣我們的工程隻要引入spring-boot-starter-web起步依賴的坐标就可以進行web開發了,同樣展現了依賴傳遞的作用。
2.3.3 自動配置原了解析
按住Ctrl點選檢視啟動類MySpringBootApplication上的注解@SpringBootApplication
@SpringBootApplication
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class);
}
}
注解@SpringBootApplication的源碼
@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 {
/**
* Exclude specific auto-configuration classes such that they will never be applied.
* @return the classes to exclude
*/
@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};
... ... ...
}
其中,
@SpringBootConfiguration:等同與@Configuration,既标注該類是Spring的一個配置類
@EnableAutoConfiguration:SpringBoot自動配置功能開啟
按住Ctrl點選檢視注解@EnableAutoConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
... ... ...
}
其中,@Import(AutoConfigurationImportSelector.class) 導入了AutoConfigurationImportSelector類
按住Ctrl點選檢視AutoConfigurationImportSelector源碼
public String[] selectImports(AnnotationMetadata annotationMetadata) {
... ... ...
List<String> configurations = getCandidateConfigurations(annotationMetadata,
attributes);
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return StringUtils.toStringArray(configurations);
}
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
return configurations;
}
其中,SpringFactoriesLoader.loadFactoryNames 方法的作用就是從META-INF/spring.factories檔案中讀取指定類對應的類名稱清單
[外鍊圖檔轉存失敗(img-WKOb472Q-1567082938173)(md_images\11.png)]
spring.factories 檔案中有關自動配置的配置資訊如下:
... ... ...
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,\
... ... ...
上面配置檔案存在大量的以Configuration為結尾的類名稱,這些類就是存有自動配置資訊的類,而SpringApplication在擷取這些類名後再加載
3. SpringBoot的配置檔案
3.1 SpringBoot配置檔案類型和作用
SpringBoot是基于約定的,是以很多配置都有預設值,但如果想使用自己的配置替換預設配置的話,就可以使用application.properties或者application.yml(application.yaml)進行配置。
SpringBoot預設會從Resources目錄下加載application.properties或application.yml(application.yaml)檔案
其中,application.properties檔案是鍵值對類型的檔案,之前一直在使用,是以此處不在對properties檔案的格式進行闡述。除了properties檔案外,SpringBoot還可以使用yml檔案進行配置,下面對yml檔案進行講解。
3.2 yml配置檔案簡介
YML檔案格式是YAML (YAML Aint Markup Language)編寫的檔案格式,YAML是一種直覺的能夠被電腦識别的的資料資料序列化格式,并且容易被人類閱讀,容易和腳本語言互動的,可以被支援YAML庫的不同的程式設計語言程式導入,比如: C/C++, Ruby, Python, Java, Perl, C#, PHP等。YML檔案是以資料為核心的,比傳統的xml方式更加簡潔。
YML檔案的擴充名可以使用.yml或者.yaml。
3.3 yml配置檔案的文法
3.3.1 配置普通資料
- 文法: key: value
- 示例代碼:
-
name: haohao
- 注意:value之前有一個空格
3.3.2 配置對象資料
-
文法:
key:
key1: value1
key2: value2
或者:
key: {key1: value1,key2: value2}
- 示例代碼:
-
person: name: haohao age: 31 addr: beijing #或者 person: {name: haohao,age: 31,addr: beijing}
- 注意:key1前面的空格個數不限定,在yml文法中,相同縮進代表同一個級别
3.3.3 配置Map資料
同上面的對象寫法
3.3.4 配置數組(List、Set)資料
-
文法:
key:
- value1
- value2
或者:
key: [value1,value2]
- 示例代碼:
-
city: - beijing - tianjin - shanghai - chongqing #或者 city: [beijing,tianjin,shanghai,chongqing] #集合中的元素是對象形式 student: - name: zhangsan age: 18 score: 100 - name: lisi age: 28 score: 88 - name: wangwu age: 38 score: 90
- 注意:value1與之間的 - 之間存在一個空格
4. spring boot 整合web開發的各架構
4.1 整合連接配接池druid
4.1.1 導入坐标依賴
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.25</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.29</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
4.1.2 yml檔案配置
- 連接配接資料庫的相關參數值
url:
username:
password:
spring:
datasource:
druid:
url: #連接配接資料庫的位址
username: #資料庫的登入帳号
password: #資料庫的登入密碼
driverClassName: com.mysql.jdbc.Driver
initialSize: 5 #初始建立連接配接數量
minIdle: 5 #最小連接配接數量
maxActive: 20 #最大連接配接數量
maxWait: 10000 #擷取連接配接最大等待時間,毫秒
testOnBorrow: true #申請連接配接時檢測連接配接是否有效
testOnReturn: false #歸還連接配接時檢測連接配接是否有效
timeBetweenEvictionRunsMillis: 60000 #配置間隔檢測連接配接是否有效的時間(機關是毫秒)
minEvictableIdleTimeMillis: 300000 #連接配接在連接配接池的最小生存時間(毫秒)
4.1.3 背景監控配置
- 在springboot的啟動類中,添加一個druid的配置bean
@Bean
public ServletRegistrationBean<StatViewServlet> druidStatViewServlet() {
ServletRegistrationBean<StatViewServlet> registrationBean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
// IP白名單 (沒有配置或者為空,則允許所有通路)
registrationBean.addInitParameter("allow", "127.0.0.1");
// IP黑名單 (存在共同時,deny優先于allow)
registrationBean.addInitParameter("deny", "");
// 設定登入druid背景的帳号
registrationBean.addInitParameter("loginUsername", "");
// 設定登入druid背景的密碼
registrationBean.addInitParameter("loginPassword", "");
registrationBean.addInitParameter("resetEnable", "false");
return registrationBean;
}
4.2 整合tkmapper和pageHelper
4.2.1 導入pom坐标
<!-- 通用mapper -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.9</version>
</dependency>
4.2.2 yml文配置
mybatis:
mapper-locations: classpath*:mapper/*.xml,classpath*:**/*Mapper.xml
#IDENTITY: MYSQL #取回主鍵的方式
#notEmpty: false #insert和update中,是否判斷字元串類型!=''
configuration:
#進行自動映射時,資料以下劃線命名,如資料庫傳回的"order_address"命名字段是否映射為class的"orderAddress"字段。預設為false
map-underscore-to-camel-case: true
# 輸出SQL執行語句 (log4j2本身可以輸出sql語句)
#log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #這種帶結果集
type-aliases-package: com.qianfeng.boot.model
pagehelper:
helper-dialect: mysql
offset-as-page-num: true
row-bounds-with-count: true #使用RowBounds分頁,需要設定為true
#page-size-zero: false
reasonable: true
4.2.3 啟動器上的注解
@SpringBootApplication
@MapperScan(basePackages = "com.qianfeng.boot.mapper")
public class DemoSpringbootThymeleafApplication {
}
- 注意:@MapperScan的包是 import tk.mybatis.spring.annotation.MapperScan;
4.3 thymeleaf整合
4.3.1 導入坐标
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
4.3.2 yml配置
spring:
thymeleaf:
suffix: .html
prefix: classpath:/templates/
check-template: true
encoding: utf-8
servlet:
content-type: text/html
cache: false
4.3.3 測試
4.3.4 thymeleaf文法介紹
- 取值
- 引入URL
- 條件判斷
- 分支-switch
- 循環
- 運算
- 日期轉換
- 字元串判斷是否為空