spring boot 筆記java
第三章,使用Spring bootweb
強烈建議支持依賴管理的構建系統,Maven或Gradle正則表達式
Spring Boot的每版本都會提供它支持的依賴列表。構建配置中不須要提供這些依賴的版本,由於Spring Boot會幫你進行管理。升級Spring Boot時,這些依賴也會隨之升級。spring
能夠本身指定版本,覆蓋Spring Boot的推薦的依賴版本,但Spring Boot和Spring Framework關聯性很強,強烈建議不要指定Spring Framework的版本。數據庫
配置項目繼承spring-boot-starter-parent。瀏覽器
1 <parent> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-parent</artifactId> 4 <version>1.5.8.RELEASE</version> 5 </parent>
只需在這裏指定<version>,其餘starters均可以忽略<version>安全
繼承starter parent後,可經過properties覆蓋某些依賴的版本服務器
例子:網絡
1 <properties> 2 <spring-data-releasetrain.version>Fowler-SR2</spring-data-releasetrain.version> 3 </properties>
當須要使用公司的標準父POM時,仍想保留依賴管理的好處,可使用scope=import依賴app
這樣就不能用properties覆蓋某些依賴的版本,而要在spring-boot-dependencies以前指定依賴的版本
1 <dependencyManagement> 2 <dependencies> 3 <!-- Override Spring Data release train provided by Spring Boot --> 4 <dependency> 5 <groupId>org.springframework.data</groupId> 6 <artifactId>spring-data-releasetrain</artifactId> 7 <version>Fowler-SR2</version> 8 <scope>import</scope> 9 <type>pom</type> 10 </dependency> 11 <dependency> 12 <groupId>org.springframework.boot</groupId> 13 <artifactId>spring-boot-dependencies</artifactId> 14 <version>1.5.8.RELEASE</version> 15 <type>pom</type> 16 <scope>import</scope> 17 </dependency> 18 </dependencies> 19 </dependencyManagement>
更改Java版本:
1 <properties> 2 <java.version>1.8</java.version> 3 </properties>
Spring Boot提供了能夠將工程打包爲一個可執行的jar包的Maven插件
繼承了Spring Boot的starter parent時,不須要指定<version>等配置
1 <build> 2 <plugins> 3 <plugin> 4 <groupId>org.springframework.boot</groupId> 5 <artifactId>spring-boot-maven-plugin</artifactId> 6 </plugin> 7 </plugins> 8 </build>
啓動器包含快速運行一個工程的依賴,並支持依賴傳遞管理
官方啓動器的命名模式:spring-boot-starter-*
第三方啓動器命名模式:*-spring-boot-starter
Spring Boot不要求特定的代碼佈局,但有一些最佳實踐
避免使用default package,由於使用 @ComponentScan, @EntityScan或 @SpringBootApplication 這些註解時會有問題,Spring Boot會讀取全部jar中的全部類
包名建議使用反轉的域名,例如:com.example.myproject
建議將主類放在根包中,
由於 @EnableAutoConfiguration常常放在主類中,而 @EnableAutoConfiguration註解隱式的定義了搜索位置
例如JPA應用, @EnableAutoConfiguration註解的類所在的包將被用來搜索 @Entity項
主類在根包中時, @ComponentScan註解主類,不用指定basePackage屬性
主類在根包中時,能夠用 @SpringBootApplication註解
典型的佈局:
1 com 2 +- example 3 +- myproject 4 +- Application.java 5 | 6 +- domain 7 | +- Customer.java 8 | +- CustomerRepository.java 9 | 10 +- service 11 | +- CustomerService.java 12 | 13 +- web 14 +- CustomerController.java
Spring Boot傾向於基於Java的配置
儘管SpringApplication.run()能夠加載XML資源,網上不少Spring的例子也是使用XML配置,但仍是建議用 @Configuration類進行配置。
沒必要將全部的 @Configuration放到一個類中, @Import能夠導入其餘配置類
能夠用 @ComponentScan來自動掃描Spring組件,包括 @Configuration註解的類
若是你就是要使用基於XML的配置,推薦仍是用 @Configuration註解的類,而後用 @ImportResource註解來加載XML配置文件。
Spring Boot會根據添加的jar依賴,自動配置。
例如,添加HSQLDB依賴後,沒有手動配置數據庫鏈接bean,Spring Boot會自動配置內存數據庫
添加 @EnableAutoConfiguration 或 @SpringBootApplication註解到你的 @Configuration類中來啓用自動配置。
一個應用中 @EnableAutoConfiguration註解只能有一個
定義本身的配置,就能替換自動配置的相應部分
例如,本身定了DataSource bean,就會覆蓋默認的內存數據庫
用--debug啓動應用,會使核心日誌的輸出級別變爲debug,並輸出自動配置報告到控制檯。
@EnableAutoConfiguration註解的exclude屬性能禁用特定的自動配置
如: @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
若是類不在classpath中,能夠用excludeName屬性來指定全限定名
還能夠用spring.autoconfigure.exclude屬性來禁用特定的自動配置
任何標準的Spring框架技術均可以定義beans和注入依賴。
爲了簡便,經常使用 @ComponentScan掃描beans,用 @Autowired構造函數注入依賴
主類放在根包中, @ComponentScan註解就不須要參數,組件會自動註冊爲Spring bean,如 @Component, @Service, @Repository, @Controller等
例如:
1 package com.example.myproject.service; 2 import org.springframework.beans.factory.annotation.Autowired; 3 import org.springframework.stereotype.Service; 4 5 @Service 6 public class DatabaseAccountService implements AccountService { 7 8 //注意使用構造函數注入容許riskAssessor字段標記爲final,意味着它接下來不能被修改 9 private final RiskAssessor riskAssessor; 10 11 @Autowired 12 public DatabaseAccountService(RiskAssessor riskAssessor) { 13 this.riskAssessor = riskAssessor; 14 } 15 16 // ... 17 18 }
@Configuration, @EnableAutoConfiguration和 @ComponentScan註解常一塊兒用,Spring Boot提供了一個方便的 @SpringBootApplication註解來代替它們
@SpringBootApplication註解等價於默認配置下的 @Configuration, @EnableAutoConfiguration和 @ComponentScan
@SpringBootApplication也提供了別名來定製 @EnableAutoConfiguration和 @ComponentScan對應的屬性
將應用打包成jar並使用內嵌HTTP服務器就能夠在任何地方運行。
調試Spring Boot應用也很容易;你沒必要使用任何特定的IDE插件或擴展。
Eclipse導入Maven工程,從File菜單選擇Import… → Existing Maven Projects
一個web應用運行兩次,會出現端口被佔用的錯誤,STS能夠用Relaunch代替Run按鈕
可執行的jar包,能夠用java -jar來運行
$ java -jar target/myproject-0.0.1-SNAPSHOT.jar
支持以遠程調試模式運行打包的應用。這會在打包的應用中添加一個調試器:
$ java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n -jar target/myproject-0.0.1-SNAPSHOT.jar
$ mvn spring-boot:run
設置操做系統環境變量
$ export MAVEN_OPTS=-Xmx1024m -XX:MaxPermSize=128M
JVM熱部署能夠替換的字節碼有限制,更好的方案是使用JRebel或Spring Loaded,spring-boot-devtools也支持快速重啓
spring-boot-devtools模塊加到任何工程中,提供程序調試功能
1 <dependencies> 2 <dependency> 3 <groupId>org.springframework.boot</groupId> 4 <artifactId>spring-boot-devtools</artifactId> 5 <optional>true</optional> 6 </dependency> 7 </dependencies>
運行完整的打包應用時,開發者工具會自動失效。
經過java -jar啓動,或經過特定的類加載器啓動的應用,會被當作『產品級應用』。
將依賴標記爲optional是爲了阻止devtools間接應用到使用你應用的其它模塊。
再打包的文件默認不包含devtools。
若是想使用devtools遠程功能,須要配置excludeDevtools屬性。
當classpath中的文件修改時,spring-boot-devtools會自動重啓應用
注意某些資源例如靜態資源和視圖模板不須要重啓應用。
在Eclipse中,保存修改的文件將引發classpath更新並觸發重啓事件。
在IDEA中,構建工程(Build → Make Project)會引發classpath更新並觸發重啓事件。
禁用shutdown hook,DevTools將不能正確工做(SpringApplication.setRegisterShutdownHook(false))。
由於DevTools依賴應用上下文的shutdown hook,在重啓期間關閉應用。
DevTools會自動忽略名爲spring-boot,spring-boot-devtools,spring-boot-autoconfigure,spring-boot-actuator和spring-boot-starter的工程引發的classpath更新,不會觸發重啓。
Spring Boot提供的重啓技術是經過兩個類加載器進行工做的。
加載進基類加載器的類不能改變(例如,那些第三方jar包)。
那些你正在開發的類加載進重啓類加載器中。
當應用重啓時,丟棄舊的重啓類加載器並建立一個新的。
這種方法意味着應用重啓時比『冷啓動』更快,由於基類加載器已經存在並可用。
若是以爲應用重啓不夠快,或碰到了類加載問題,能夠考慮重載技術,例如ZeroTurnaround的JRebel。
重載技術經過加載時重寫類使其更適合重載。
某些資源改變時不須要觸發重啓,例如,Thymeleaf模板能夠就地編輯。
默認狀況下,/META-INF/maven,/META-INF/resources,/resources,/static,/public或/templates中資源的改變不會觸發重啓,但會觸發實時重載。
若是想定製這些例外項,可使用spring.devtools.restart.exclude屬性。
例如,僅排除/static和/public,設置以下:
spring.devtools.restart.exclude=static/**,public/**
保持默認設置的同時添加例外項,能夠用spring.devtools.restart.additional-exclude屬性。
用spring.devtools.restart.additional-paths屬性能夠監控classpath以外其它路徑上的變化。
能夠用spring.devtools.restart.exclude屬性來控制其它路徑上的變化的觸發效果,是觸發重啓仍是僅觸發實時重載。
經過application.properties中設置spring.devtools.restart.enabled屬性禁用,仍會初始化重啓類加載器但不會監控文件的變化
要徹底禁用重啓,調用SpringApplication.run(…)以前設置System屬性:
1 public static void main(String[] args) { 2 System.setProperty("spring.devtools.restart.enabled", "false"); 3 SpringApplication.run(MyApp.class, args); 4 }
想在特定的時間觸發重啓,可使用『觸發器文件』
修改『觸發器文件』只觸發重啓檢查,Devtools決定是否重啓。
設置spring.devtools.restart.trigger-file屬性來使用觸發器文件
將spring.devtools.restart.trigger-file做爲全局設置,能夠應用到全部的工程
建立META-INF/spring-devtools.properties文件
spring-devtools.properties中能夠設置包含restart.exclude.和restart.include.前綴的屬性。
include元素會放到「restart」類加載器中,exclude元素會放到「base」類加載器中。
屬性值是應用到classpath中的一個正則表達式。
例如:
restart.exclude.companycommonlibs=/mycorp-common-[\\w-]+\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar
全部屬性Key必須是惟一的。
restart.include.或restart.exclude只要配置了就會應用。
能夠將META-INF/spring-devtools.properties文件打包進工程中,也能夠是工程使用的庫中,都會被加載。
使用標準ObjectInputStream進行反序列化對象時,重啓功能可能有問題。
可使用Spring的ConfigurableObjectInputStream和Thread.currentThread().getContextClassLoader()反序列化數據
有些第三方庫反序列化時沒有考慮上下文類加載器,只能請求原做者修正。
spring-boot-devtools模塊包含一個內嵌的實時重載服務器,當資源改變時能夠用來觸發瀏覽器從新刷新。
livereload.com中的實時重載瀏覽器擴展可用於Chrome,Firefox和Safari
不想啓動實時重載服務器,能夠將spring.devtools.livereload.enabled屬性設爲false
一次只能運行一個實時重載服務器。從IDE中啓動多個應用,只有第一個應用支持實時重載服務器。
$HOME文件夾中,添加 .spring-boot-devtools.properties文件,能夠對開發者工具進行全局設置(注意文件名以.開頭)
如:
~/.spring-boot-devtools.properties.
spring.devtools.reload.trigger-file=.reloadtrigger
Spring Boot開發者工具不是本地環境才能用,有些功能能夠用於遠程應用。
再打包的文件中包含devtools,才能開啓遠程支持:
1 <build> 2 <plugins> 3 <plugin> 4 <groupId>org.springframework.boot</groupId> 5 <artifactId>spring-boot-maven-plugin</artifactId> 6 <configuration> 7 <excludeDevtools>false</excludeDevtools> 8 </configuration> 9 </plugin> 10 </plugins> 11 </build>
還要設置spring.devtools.remote.secret屬性
例如:
spring.devtools.remote.secret=mysecret
遠程devtools有安全風險,生產環境不該該開啓遠程支持。
遠程devtools分爲兩部分:
一個接收鏈接的服務器端,一個運行在IDE中的客戶端應用。
當設置spring.devtools.remote.secret屬性時,服務器組件會自動起做用。客戶端組件必須手動啓動。
遠程客戶端要運行在 IDE 中。要與遠程服務器端使用相同的 classpath ,以便運行 org.springframework.boot.devtools.RemoteSpringApplication。要鏈接的遠程 URL做爲參數傳入。
由於遠程客戶端與遠程服務器端使用的classpath相同,所以它能夠直接讀取應用屬性。
爲了傳輸的安全性,建議老是使用HTTPS協議。
要使用代理訪問遠程應用,則要配置spring.devtools.remote.proxy.host和spring.devtools.remote.proxy.port屬性。
遠程客戶端會像本地重啓那樣監控應用的classpath的變化。
任何資源的更新都會推送到遠程應用並在須要時觸發重啓。
若是你在迭代開發一個功能,這個功能使用了本地沒有的雲服務,這時遠程更新就頗有用。
一般更新和重啓比整個從新構建部署更快。
當遠程客戶端運行時只監控文件。若是在啓動遠程客戶端以前你修改了文件,它將不會推送到遠程服務器。
在診斷遠程應用的問題時,Java遠程調試頗有用。
devtools 支持經過 HTTP 實現遠程調試的通道。
遠程客戶端提供了在8000端口上的本地服務,你能夠在這上面添加一個遠程調試器。
創建鏈接後,調試通訊將經過 HTTP 發送到遠程應用。
若是要使用不一樣的端口,可使用 spring.devtools.remote.debug.local-port 屬性。
使用遠程調試通道須要確保遠程應用啓動時啓用了遠程調試。
能夠經過配置 JAVA_OPTS 來實現。例如,使用 Cloud Foundry,您能夠向您的 manifest.yml 添加如下內容:
---
env:
JAVA_OPTS: "-Xdebug -Xrunjdwp:server=y,transport=dt_socket,suspend=n"
注意:不須要在 -Xrunjdwp 中設置 address=NNNN 。省略address,Java會簡單的選擇一個隨機的可用的端口。
經過網絡調試遠程服務可能很慢,可能須要在 IDE 中增長超時時間。
例如,在 Eclipse 中,能夠從Preferences…選擇Java → Debug,並將Debugger timeout (ms)改爲更合適的值(在大多數狀況下,60000能夠正常工做)。
可執行的 jar 能夠用於生產部署。因爲它們是自包含的,它們也很是適合基於雲的部署。