天天看點

springboot 自動配置微調

在處理應用安全時,我們當然希望完全掌握所有的配置。但是為了微調一些細節,我們就放棄自動配置的話。顯得有些因噎廢食。

springboot 自動配置的bean提供了300多個使用者微調的屬性。當我們要調整設定時,隻要在環境變量、java系統屬性、JNDI、指令行參數或者屬性檔案裡進行指定就好了。

Spring Boot能從多種屬性源獲得屬性,包括如下幾處。(1) 指令行參數(2) java:comp/env 裡的JNDI屬性(3) JVM系統屬性(4) 作業系統環境變量(5) 随機生成的帶 random.* 字首的屬性(在設定其他屬性時,可以引用它們,比如 ${random.long} )(6) 應用程式以外的application.properties或者appliaction.yml檔案(7) 打包在應用程式内的application.properties或者appliaction.yml檔案(8) 通過 @PropertySource 标注的屬性源(9) 預設屬性這個清單按照優先級排序,也就是說,任何在高優先級屬性源裡設定的屬性都會覆寫低優先級的相同屬性。例如,指令行參數會覆寫其他屬性源裡的屬性。application.properties和application.yml檔案能放在以下四個位置。(1) 外置,在相對于應用程式運作目錄的/config子目錄裡。(2) 外置,在應用程式運作的目錄裡。(3) 内置,在config包内。(4) 内置,在Classpath根目錄。同樣,這個清單按照優先級排序。也就是說,/config子目錄裡的application.properties會覆寫應用程式Classpath裡的application.properties中的相同屬性。此外,如果你在同一優先級位置同時有application.properties和application.yml,那麼application.yml裡的屬性會覆寫application.properties裡的屬性。

自動配置微調

(1) 禁用模闆緩存

如果閱讀清單應用程式經過了幾番修改,我們注意到,除非重新開機應用程式,否則對Thymeleaf模闆的變更是不會生效的。這是因為Thymeleaf模闆預設緩存。這有助于改善應用程式的性能,因為模闆隻需編譯一次,但在開發過程中就不能實時看到變更的效果了。将 spring.thymeleaf.cache 設定為 false 就能禁用Thymeleaf模闆緩存。在指令行裡運作應用程式時,将其設定為指令行參數即可:$ java -jar readinglist-0.0.1-SNAPSHOT.jar --spring.thymeleaf.cache=false或者,如果你希望每次運作時都禁用緩存,可以建立一個application.yml,包含以下内容:spring:thymeleaf:cache: false你一定要確定這個檔案不會釋出到生産環境,否則生産環境裡的應用程式就無法享受模闆緩存帶來的性能提升了。作為開發者,在修改模闆時始終關閉緩存實在太友善了。為此,可以通過環境變量來禁用Thymeleaf緩存:$ export spring_thymeleaf_cache=false此處使用Thymeleaf作為應用程式的視圖,Spring Boot支援的其他模闆也能關閉模闆緩存,設定這些屬性就好了: spring.freemarker.cache (Freemarker) spring.groovy.template.cache (Groovy模闆) spring.velocity.cache (Velocity)預設情況下,這些屬性都為 true ,也就是開啟緩存。将它們設定為 false 即可禁用緩存。

(2)配置嵌入式伺服器

從指令行(或者Spring Tool Suite)運作Spring Boot應用程式時,應用程式會啟動一個嵌入式的伺服器(預設是Tomcat),監聽8080端口。大部分情況下這樣挺好,但同時運作多個應用程式可能會有問題。要是所有應用程式都試着讓Tomcat伺服器監聽同一個端口,在啟動第二個應用程式時就會有沖突。無論出于什麼原因,讓伺服器監聽不同的端口,你所要做的就是設定 server.port 屬性。要是隻改一次,可以用指令行參數:$ java -jar readinglist-0.0.1-SNAPSHOT.jar --server.port=8000但如果希望端口變更時間更長一點,可以在其他支援的配置位置上設定 server.port 。例如,把它放在應用程式Classpath根目錄的application.yml檔案裡:server: port: 8000除了伺服器的端口,你還可能希望伺服器提供HTTPS服務。為此,第一步就是用JDK的keytool 工具來建立一個密鑰存儲(keystore):$ keytool -keystore mykeys.jks -genkey -alias tomcat -keyalg RSA該工具會詢問幾個與名字群組織相關的問題,大部分都無關緊要。但在被問到密碼時,一定要記住你的選擇。在本例中,我選擇letmein作為密碼。現在隻需要設定幾個屬性就能開啟嵌入式伺服器的HTTPS服務了。可以把它們都配置在指令行裡,但這樣太不友善了。可以把它們放在application.properties或application.yml裡。在application.yml中,它們可能是這樣的:server:port: 8443ssl:key-store: file:///path/to/mykeys.jks

key-store-password: letmeinkey-password: letmein此處的 server.port 設定為8443,開發環境的HTTPS伺服器大多會選這個端口。server.ssl.key-store 屬性指向密鑰存儲檔案的存放路徑。這裡用了一個file://開頭的URL,從檔案系統裡加載該檔案。你也可以把它打包在應用程式的JAR檔案裡,用 classpath: URL 來引用它。 server.ssl.key-store-password 和 server.ssl.key-password 設定為建立該檔案時給定的密碼。有了這些屬性,應用程式就能在8443端口上監聽HTTPS請求了。(根據你所用的浏覽器,可能會出現警告框提示該伺服器無法驗證其身份。在開發時,通路的是localhost,這沒什麼好擔心的。)

(3)配置日志

大多數應用程式都提供了某種形式的日志。即使你的應用程式不會直接記錄日志,你所用的庫也會記錄它們的活動。預設情況下,Spring Boot會用Logback(

http://logback.qos.ch

)來記錄日志,并用 INFO 級别輸出到控制台。在運作應用程式和其他例子時,你應該已經看到很多 INFO 級别的日志了。如果想更換成log4j2後續我們會在寫一篇文章來說如何進行springboot的日志配置。

(4)配置資料源

此時,我們還在開發閱讀清單應用程式,嵌入式的H2資料庫能很好地滿足我們的需要。一旦要投放到生産環境,我們可能要考慮更持久的資料庫解決方案。雖然我們可以顯式配置自己的 DataSource Bean,但通常并不用這麼做,隻需簡單地通過屬性配置資料庫的URL和身份資訊就可以了。舉例來說,用的是MySQL資料庫,你的application.yml檔案看起來可能是這樣的:spring:datasource:url: jdbc:mysql://localhost/readinglistusername: dbuserpassword: dbpass通常你都無需指定JDBC驅動,Spring Boot會根據資料庫URL識别出需要的驅動,但如果識别出問題了,你還可以設定 spring.datasource.driver-class-name 屬性:spring:datasource:url: jdbc:mysql://localhost/readinglist

username: dbuserpassword: dbpassdriver-class-name: com.mysql.jdbc.Driver

在自動配置 DataSource Bean的時候,Spring Boot會使用這裡的連接配接資料。 DataSourceBean是一個連接配接池,如果Classpath裡有Tomcat的連接配接池 DataSource ,那麼就會使用這個連接配接池;否則,Spring Boot會在Classpath裡查找以下連接配接池: HikariCP Commons DBCP Commons DBCP 2這裡列出的隻是自動配置支援的連接配接池,你還可以自己配置 DataSource Bean,使用你喜歡的各種連接配接池。你也可以設定 spring.datasource.jndi-name 屬性,從JNDI裡查找 DataSource :spring:datasource:jndi-name: java:/comp/env/jdbc/readingListDS一旦設定了 spring.datasource.jndi-name 屬性,其他資料源連接配接屬性都會被忽略,除非沒有設定别的資料源連接配接屬性。有很多影響Spring Boot自動配置元件的方法,隻需設定一兩個屬性即可。但這種配置外置的方法并不局限于Spring Boot配置的Bean。讓我們看看如何使用這種屬性配置機制來微調自己的應用程式元件。