本文參考自 Spring Boot文檔 。
Spring Boot 簡介
Spring架構功能很強大,但是就算是一個很簡單的項目,我們也要配置很多東西。是以就有了Spring Boot架構,它的作用很簡單,就是幫我們自動配置。Spring Boot架構的核心就是自動配置,隻要存在相應的jar包,Spring就幫我們自動配置。如果預設配置不能滿足需求,我們還可以替換掉自動配置類,使用我們自己的配置。另外,Spring Boot還內建了嵌入式的Web伺服器,系統監控等很多有用的功,讓我們快速建構企業及應用程式。
建立項目
建立項目很簡單。如果使用STS的話,建立Spring Starter項目即可。如果使用IDEA的話,建立Spring Initializer項目。如果不想使用IDE的話,從
start.spring.io建立項目也可以。例如下面就是一個Spring Boot項目的
build.gradle
檔案,是我用IDEA建立的項目。由于我是用了最新的快照版本,是以這裡的倉庫還多了兩個Spring的快找倉庫,可以直接無視。(因為1.5的穩定版中Thymeleaf的支援才到2,為了使用最新Thymeleaf3,隻能使用最新的快照版。)
我們可以看到Spring Boot和一般的項目差不多,隻不過多應用了Spring Boot插件,它會讓我們更友善的運作Spring。另外在項目中沒有其他依賴的引用,隻引用了Spring Boot Starter依賴,這些依賴會将可能會使用到的依賴幫我們引用。例如
spring-boot-starter-test
會引用JUnit、AssertJ等一些測試架構,我們不用再引用了。這極大地友善了我們的開發。而且這些依賴不需要指定具體版本,具體的版本由Spring幫我們決定。關于詳細的Starter項目和具體jar包的版本号,參考
13.5. Starters和
F. Dependency versionsbuildscript {
ext {
springBootVersion = '2.0.0.BUILD-SNAPSHOT'
}
repositories {
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
jar {
baseName = 'spring-boot-sample'
version = '0.0.1-SNAPSHOT'
}
sourceCompatibility = 1.8
repositories {
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-aop')
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
compile('org.springframework.boot:spring-boot-starter-web')
runtime('org.springframework.boot:spring-boot-devtools')
runtime('org.hsqldb:hsqldb')
runtime('mysql:mysql-connector-java')
compileOnly('org.projectlombok:lombok')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
項目格式
項目格式類似下圖,和一般的Maven或者Gradle項目類似,隻不過多了點東西。資源檔案夾下
static
檔案夾用來存放web程式的靜态資源,例如圖檔、css、js等。
template
檔案夾存放web程式的視圖模闆,html等需要渲染的模闆檔案就放在這裡。
application.properties
檔案很重要,它是Spring Boot項目的全局配置檔案。以往我們需要編寫層級XML配置檔案,現在隻需要在這裡使用
key=value
方式即可指定這些屬性。預設的模闆還為我們添加了兩個類。一個在main下,是Spring Boot項目的運作類,另一個在test下,是測試類。

運作類的代碼如下。它是一個簡單的類,包含了主方法,而且類上使用了@SpringBootApplication注解。這是一個慣用注解,它會幫我們啟用自動配置等特性。
@SpringBootApplication
public class SpringBootSampleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootSampleApplication.class, args);
}
}
如果看一下
SpringBootApplication
的源代碼,類似下面這樣。可以看到,
SpringBootApplication
的功能是通過幾個注解實作的。
EnableAutoConfiguration
注解啟用了自動配置功能。
ComponentScan
注解會掃描該類所在的包和子包。是以Spring推薦我們将這個運作類放到項目的根包下,以便我們不需要任何配置即可掃描到所有配置類。
@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 {
Spring Boot項目更喜歡Java配置方式。是以從這裡開始,所有的Spring配置都是用Java方式配置。當然如果你還想使用XML配置檔案也可以,建立一個空的配置類,然後添加
@ImportResource
注解并傳遞要使用的XML檔案路徑即可。
運作項目
如果使用Maven的話,運作下面的指令。
mvn spring-boot:run
如果使用Gradle的話,使用下面的指令。
gradle bootRun
然後就會顯示類似下面的輸出,後面會跟一大堆日志資訊。如果是指令行程式的話,日志資訊之後就會顯示程式的運作結果了。如果是Web程式的話,預設情況下會使用内嵌的Tomcat來運作。我們使用
localhost:8080
來通路即可。
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.0.0.BUILD-SNAPSHOT)
這個日志可以是彩色的。如果你的輸出不是彩色的,可以在
application.properties
檔案中添加下面一句。
spring.output.ansi.enabled=always
項目配置
自定義 SpringApplication
前面我們看到了SpringBoot項目的啟動類是這樣的。
@SpringBootApplication()
public class SpringBootSampleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootSampleApplication.class, args);
}
}
其實,我們可以自定義它的各種屬性。這時候需要建立SpringApplication對象并設定它的各種屬性。比方說下面不顯示Banner。還有很多配置和用法請查閱官方文檔。
@SpringBootApplication()
public class SpringBootSampleApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(SpringBootSampleApplication.class);
application.setBannerMode(Banner.Mode.OFF);
application.run(args);
}
}
事件和監聽器
如果有更進階的需求可以使用監聽器來管理Spring Boot程式的各個生命周期。監聽器需要實作
org.springframework.context.ApplicationListener
接口。
public class MyAppListener implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
System.out.println("應用程式準備就緒");
}
}
在監聽器中可以設定下面幾種事件。
- ApplicationStartingEvent
- ApplicationEnvironmentPreparedEvent
- ApplicationPreparedEvent
- ApplicationReadyEvent
- ApplicationFailedEvent
之後,把監聽器添加到Spring程式中。
@SpringBootApplication()
public class SpringBootSampleApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(SpringBootSampleApplication.class);
application.setBannerMode(Banner.Mode.OFF);
application.addListeners(new MyAppListener());
application.run(args);
}
}
Profiles
在Spring Boot中Profiles更簡單了。我們使用
application-{profile}.properties
格式來區分不同的Profile,例如一個測試profile(
application-test.properties
),一個生産環境profile(
application-product.properties
)。
定義好多個Profiles之後,還需要在标準的
application.properties
中列出和啟用這些Profiles。列出使用
spring.profiles.include
,激活其中的一個使用
spring.profiles.active
spring.output.ansi.enabled=always
spring.thymeleaf.cache=false
spring.profiles.include[0]=test
spring.profiles.include[1]=product
spring.profiles.active[0]=test
使用YAML
YAML也是一種配置檔案格式,比方說上面的properties,就可以改寫為下面這樣的YAML檔案(
application.yaml
spring:
output:
ansi:
enabled: always
thymeleaf:
cache: false
profiles:
include:
- product
- test
active: test
如果需要多個Profile,YAML隻需要一個檔案即可,profiles之間使用
---
分隔開。
server:
address: 192.168.1.100
---
spring:
profiles: development
server:
address: 127.0.0.1
---
spring:
profiles: production
server:
address: 192.168.1.120
使用Properties還是YAML,根據個人喜好即可。
自動配置
修改自動配置
Spring Boot的核心就是自動配置,它為幾乎所有的Spring元件都提供了相應的自動配置類,而且預設是打開的。是以隻要相關的jar檔案存在,這些自動配置就會被使用。其中有些配置屬于必配的(例如Web模闆),自動配置會為我們省下不少時間;有些配置(例如資料源)則往往需要我們修改。Spring的自動配置是非侵入式的,是以如果我們聲明了自己的資料源,那麼Spring自動配置的嵌入式資料源就會取消。
當然如果想要關閉某些自動配置也是可以的。如果你有自己的主配置類,手動在上排除某些自動配置類即可。
@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class MyConfiguration {
}
如果我們使用了
SpringBootApplication
注解,那麼上面這種方式需要修改一下。
SpringBootApplication
注解提供了幾個屬性,可以控制排除的自動配置群組件搜尋的路徑。
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class SpringBootSampleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootSampleApplication.class, args);
}
}
另外還可以直接修改項目的屬性。我們可以編輯
application.properties
檔案,在其中添加
spring.autoconfigure.exclude
屬性并指定要排除的類即可。
Spring的自動配置類一般在
org.springframework.boot.autoconfigure
包下,如果我們需要檢視目前使用了多少個自動配置類,可以在運作程式的時候添加
--debug
标志,這樣Spring會列印額外的調試資訊。如果需要詳細的自動配置類的清單,可以參考
Spring Boot文檔 附錄C. Auto-configuration classesSpring Web MVC自動配置
MVC自動配置會啟用以下功能。
-
ContentNegotiatingViewResolver
beans.BeanNameViewResolver
- 靜态資源和WebJars的支援.
- 自動注冊
,Converter
GenericConverter
Formatter
-
的支援.HttpMessageConverters
-
.MessageCodesResolver
- 靜态
index.html
- 自定義Favicon(浏覽器頁面的小圖示) 支援.
- 自動使用ConfigurableWebBindingInitializer bean.
自動注冊指的是,隻需要在Spring中注冊相應類型的Bean。Spring Web MVC會自動識别和使用這些Bean。例如,我們要添加新的
HttpMessageConverter
,隻需要向下面這樣。
@Configuration
public class MyConfiguration {
@Bean
public HttpMessageConverters customConverters() {
HttpMessageConverter<?> additional = ...
HttpMessageConverter<?> another = ...
return new HttpMessageConverters(additional, another);
}
}
靜态資源
靜态資源預設放在resources檔案夾的
/static
(或
/public
或
/resources
/META-INF/resources
下面。如果需要配置位置的話,在屬性檔案中添加
spring.mvc.static-path-pattern=/resources/**
如果需要靜态首頁,直接在
resources/static/
下放入一個
index.html
即可。
favicon.ico
如果需要配置自己的
favicon.ico
,隻需要将自己的
favicon.ico
直接放到resources檔案夾下即可。
視圖模闆
Spring會對Thymeleaf、Freemarker、Groovy和mustache四種模闆進行自動配置。預設的模闆路徑為
resources/templates
錯誤處理
錯誤處理和一般的Spring Web MVC類似,使用
@ControllerAdvice
自定義錯誤頁面放在下面的路徑。
src/
+- main/
+- java/
| + <source code>
+- resources/
+- public/
+- error/
| +- 404.html
+- <other public assets>
如果錯誤頁面也需要使用模闆引擎動态生成,那麼放在下面的路徑。
src/
+- main/
+- java/
| + <source code>
+- resources/
+- templates/
+- error/
| +- 5xx.ftl
+- <other templates>
SQL資料庫自動配置
嵌入式資料庫
如果類路徑中包含HSQL、Derby或H2的相應jar包,那麼Spring就會自動配置這些嵌入式資料庫的執行個體和資料源。它們會将資料儲存在記憶體中,當程式結束之後資料會丢失。這非常适合開發和測試。
在不同的測試中Spring預設會重用這些嵌入式資料庫。假如不同測試之間的資料不同,你可能希望每次測試都使用新的資料庫。這時候可以在屬性檔案中指定
spring.datasource.generate-unique-name=true
生産資料庫
Spring會自動選擇帶連接配接池的資料源,遵循以下規則:
- 如果存在tomcat-jdbc資料源,則使用它。
- 否則,如果存在HikariCP,則使用它。
- 如果前兩個都不存在,而存在DBCP2,則使用它。
這時候我們需要提供資料源的額外配置資訊。
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
JdbcTemplate
JdbcTemplate
NamedParameterJdbcTemplate
會由上面的資料源自動配置。我們直接使用@Autowire注入到程式中即可。
JPA自動配置
實體類
JPA Entity類(标記了@Entity的類)預設在
persistence.xml
中配置。在Spring Boot中,
@EnableAutoConfiguration
@SpringBootApplication
包下的實體類會被自動掃描到。如果希望自定義實體類的位置,可以使用
@EntityScan
注解,添加到配置類上即可。
Spring Data JPA
繼承了
Repository
的接口會被自動掃描到,我們不需要做任何配置。如果需要配置,設定
spring.jpa.*
屬性。例如下面指定了資料的生成政策。
spring.jpa.hibernate.ddl-auto=update
H2的web控制台
H2嵌入式資料庫提供了一個基于web界面的控制台。這個控制台也可以由Spring自動配置。當(1:存在H2相關jar包,2:目前程式是一個web程式,3:devtoos存在)的情況下,Spring便會自動配置H2控制台。
web控制台的通路路徑預設為
/h2-console
。我們可以使用
spring.h2.console.path
屬性修改它。
H2 web控制台
如圖,這是一個完整的互動界面,我們可以友善的在這裡處理資料。如果需要設定通路控制權限,添加下面的屬性。
- security.user.role
- security.basic.authorize-mode
- security.basic.enabled
如果不想使用該控制台,可以使用
spring.h2.console.enabled=false
關閉它。在生産環境中記得把它關掉。
最後我要說一點,Spring Boot文檔包含了很多其他Spring項目的自動配置,這裡不可能全寫完。是以如果需要詳細資訊的話還是直接啃文檔吧。
其他配置
調試工具(devtools)
如果使用Maven,添加下面的依賴。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
如果使用Gradle,添加下面的依賴。
dependencies {
compile("org.springframework.boot:spring-boot-devtools")
}
這樣就可以将調試工具添加到項目中。調試工具添加了熱更新、自動重新開機等幾個非常有用的調試功能。自動重新開機需要Spring檢測到類路徑上有更改,在Spring Tool Suite中,簡單的儲存檔案即可達到效果。如果在Intellij IDEA中,隻能選擇Build Project。
輸出日志
Spring Boot預設使用Logback來列印日志。不過我們直接使用slf4j提供的接口就可以了。slf4j和Logback也都由Spring自動配置好了。我們隻需要在屬性檔案中設定日志級别即可。
logging.level.yitian.study=debug
然後在代碼中調用slf4j的日志接口并列印日志即可。
@Controller
public class MainController {
private Logger logger = LoggerFactory.getLogger(MainController.class);
@RequestMapping("/")
public String index(@RequestParam(defaultValue = "苟") String name, Model model) {
model.addAttribute("name", name);
logger.debug("通路了首頁");
return "index";
}
}
日志資訊和Spring的輸出格式一樣。另外随着日志級别的變化,日志的顔色也會在綠、黃和紅之間變化,非常友善。
2017-03-16 23:50:19.628 INFO 17220 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 4 ms
2017-03-16 23:50:19.632 ERROR 17220 --- [nio-8080-exec-1] yitian.study.controller.MainController : 通路了首頁
自定義Banner
這個Banner也是可以定制的。在類路徑(也就是resource檔案夾下)添加
banner.txt
,Banner就會使用你的文本。Banner甚至可以是一張圖檔,支援gif、jpg、png等格式。Spring會将圖檔轉換成字元形式。
Servlet容器
預設情況下Spring使用Tomcat作為嵌入式容器。
端口号
端口号使用
server.port
設定。如果希望在運作時随機配置設定一個未使用的端口号,可以将端口号設定為0:
server.port=0
使用Jetty
spring-boot-starter-web
包預設使用Tomcat,如果我們希望使用Jetty,就需要排除Tomcat的包。使用Maven的話,這麼做。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
如果使用Gradle的話,這麼做。
configurations {
compile.exclude module: "spring-boot-starter-tomcat"
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:2.0.0.BUILD-SNAPSHOT")
compile("org.springframework.boot:spring-boot-starter-jetty:2.0.0.BUILD-SNAPSHOT")
// ...
}
響應壓縮
使用
server.compression.enabled=true
啟用HTTP的響應壓縮。預設情況下要壓縮的響應體至少需要2048位元組,可以使用
server.compression.min-response-size
修改這個值。
打包和運作
Spring Boot項目預設打包為jar檔案。我們可以使用Maven或Gradle的打包指令來打包項目。打包好之後,就可以和一般jar檔案一樣,使用java指令來運作了。如果希望打包為war檔案的話也可以,不過由于篇幅所限就不介紹了。直接看源文檔吧。
系統監控(Actuator)
Actuator我沒了解怎麼翻譯,是以憑我的感覺就叫做系統監控吧。這些功能可以幫助我們監控正在運作的Spring Boot項目。要啟用監控功能,需要添加
spring-boot-starter-actuator
。使用Maven的話,添加下面的依賴。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
如果使用Gradle的話,添加下面的依賴。
dependencies {
compile("org.springframework.boot:spring-boot-starter-actuator")
}
端點(Endpoints)
每個端點就是一個監控項。Spring包含了很多端點,詳細清單在這裡
47. Endpoints。除了health之外,其餘端點都屬于敏感資訊,在沒有設定Spring Security的情況下無法通路。為了簡單的在本地通路,我們可以設定
management.security.enabled=false
。注意該選項在生産環境中務必打開,保證伺服器資訊不會洩露。
端點的通路路徑預設是
/端點名
,例如health的通路路徑就是
/health
。比較有用的幾個端點是beans(列出目前所有已注冊的Spring Beans)、mappings(所有的控制器映射路徑)、trace(最近100個HTTP連接配接的資訊)、health(伺服器目前的運作狀态和磁盤剩餘空間以及資料庫的運作狀态)。還有一個有趣的端點是shutdown,當我們向
/shutdown
發送post請求時伺服器就會關閉,不過該功能是預設關閉的。
端點可以在屬性檔案中設定,每個端點敏感性和是否啟用都是可以定制的。
endpoints.beans.sensitive=false
endpoints.shutdown.enabled=true
端點的通路也是可以定制的。
management.port=8081
management.address=127.0.0.1
好了,Spring Boot架構的介紹到此為止。我們已經基本看到了Spring Boto的使用方法。當然官方文檔還有很多内容這裡沒有列出。這裡也不可能完全列出來。如果需要更詳細的介紹還是直接看官方文檔吧。沒有比這個更全面的了。