A. Spring Boot 外置配置文件
默認情況下,我們 spring boot 項目的配置文件<small>(application.yaml、application.properties)</small>是在項目的 jar 包『裡面』的。
如果是要改配置文件中的配置項時,就需要將項目重新打包,在某些情況下,這就顯得十分不方便。
對此,我們可以將 spring boot 項目的配置文件『挪到』jar 包之外,然後再啟動 spring boot 項目時再指定它使用外部的這些配置文件。
根據上述的 <outputDirectory> 的配置,相關的配置文件會被復制到 target 下的 resources 目錄中,並且,jar 包中也不會包含你所配置的這些配置文件。
這種情況下,在啟動 spring boot 項目時,需要額外的參數( -Dspring.config.location )告訴它項目的配置文件在哪:
注意:
spring boot 默認是以 classpath:/,classpath:/config/,file:./,file:./config/ 這樣的配置在查找、載入配置文件,有意思的是查找順序是上述配置的反向順序:
因此,如果你在 spring.config.location 中也定義了多個配置文件位置,例如: classpath:/custom-config/,file:./custom-config/ , 那麼配置文件的查找、載入順序同樣是反向的:
另外,還有一個功能相似的配置 spring.config.additional-location ,使用它的話,它會作為默認配置路徑的『 擴展配置 』路徑來使用。擴展的配置路徑會比默認的配置優先被掃描到. 比如說, 如果設置了擴展的配置文件所在路徑為: classpath:/custom-config/,file:./custom-config/ , 那麼查找路徑將會是下面的順序:
這種掃描順序使得你可以通過自己的自定義配置來修改默認的配置項。
B. SpringBoot的配置文件有哪幾種格式
SpringBoot中的配置文件來主要有三種格式,自properties、yaml、和xml方式。
- 其中properties格式配置文件後綴是.properties,配置項為:server.port = 9090
- yaml格式配置文件後綴是.yml,配置項是:server.port: 9090
在SpringBoot中,使用最廣泛的配置文件是yaml,yaml之所以流行,除了他配置語法精簡之外,還因為yaml是一個跨編程語言的配置文件。
在SpringBoot中,除了yaml之外,properties也比較常用,但是XML幾乎不用,看得出來Spring團隊非常痛恨XML配置文件!認為它不是一個好的語言。
如果你對常見的配置文件有哪幾種格式不熟悉,就去黑馬程序員官網視頻庫看免費視頻。
C. springboot配置文件總結
springboot 本身支持多種靈活的配置方式,為開發 springboot 程序帶來了很大的靈活性和擴展性,但是同時由於太靈活,經常會導致明明配置了相關屬性,卻沒有生效。
本文總結了 springboot 配置文件的原理以及多個配置文件生效的順序。
springboot 配置文件支持靈活的路徑,以及靈活的文件名,用一個變數表達式總結如下:
部分源碼如下:
當滿足上述變數表達式的配置文件有多個時,會有一個配置的優先順序。假設
上面每個條件組合起來,則最多有配置文件如下,且順序從上到下:
獲取屬性時,按從上到下的順序遍歷由上述文件生成的屬性資源對象 PropertySource ,如果遇到匹配的key直接返回。
總結一下:就是如果同一個key的屬性只出現一次,則直接取該值即可。如果同一個key的屬性出現多次,則取順序靠前的屬性資源對象。另外其中每個文件都是可選的。
需要注意的一點是:如果在同一個 location 下配置了多個文件名一樣的文件,則只會取一個,比如在 classpath:/ ,有如下兩個文件 application.yml :
則只會根據 classloader 的 classpath 列表,選取第一個出現的文件。因為 springboot 載入配置文件時最底層是使用的下面的方法:
這兩個方法只會獲取 classloader 類的 ucp 屬性裡面第一個匹配到的值。如果對 springboot 自身的機制不滿意,想獲取所有的classpath:/路徑下面的 applicaiton.yml 文件,可以使用下面的方法:
本文總結了 springboot 配置文件的原理以及多個配置文件生效的順序。如果存在增加了配置文件或者在配置文件裡面增加了屬性卻沒有生效,可以參考上面的 springboot 配置文件表達式和配置文件生效順序進行排查。
後面還會有一篇文章討論基於 springboot 配置原理如何實現自定義的配置讀取方式。
D. Spring MVC 配置文件講解
使用@Controller定義一個控制器
使用@RequestMapping映射請求
使用@RequestParam綁定請求參數到方法參數
使用@ModelAttribute提供一個從模型到數據的鏈接
使用@SessionAttributes指定存儲在會話中的屬性
<context:annotation-config/>
他的作用是隱式地向 Spring 容器注冊
、
、
、
這 4 個BeanPostProcessor。
例如:
如果想使用@ Resource 、@ PostConstruct、@ PreDestroy等註解就必須聲明。
如果想使用@PersistenceContext註解,就必須聲明的Bean。
如果你想使用@Autowired註解,那麼就必須事先在 Spring 容器中聲明 Bean。傳統聲明方式如下:
<bean class="org.springframework.beans.factory.annotation. "/>
如果想使用 @Required的註解,就必須聲明的Bean。同樣,傳統的聲明方式如下:
<bean class="org.springframework.beans.factory.annotation."/>
記得,使用註解一般都會配置掃描包路徑選項
<context:component-scan base-package=」XX.XX」/>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcherServlet-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
這個配置常常見於web.xml文件中
<load-on-startup>1</load-on-startup>是啟動順序,讓這個Servlet隨Servletp容器一起啟動。
<url-pattern>*.do</url-pattern> 會攔截*.do結尾的請求。
<servlet-name>dispatcherServlet</servlet-name>這個Servlet的名字是dispatcherServlet,可以有多個DispatcherServlet,是通過名字來區分的。每一個DispatcherServlet有自己的WebApplicationContext上下文對象。同時保存的ServletContext中和Request對象中,關於key,以後說明。
在DispatcherServlet的初始化過程中,框架會在web應用的 WEB-INF文件夾下尋找名為[dispatcherServlet]-servlet.xml 的配置文件,生成文件中定義的bean。
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcherServlet-servlet.xml</param-value>
</init-param>
指明了配置文件的文件名,不使用默認配置文件名,而使用springMVC.xml配置文件。
其中<param-value>**.xml</param-value> 這里可以使用多種寫法
1、不寫,使用默認值:/WEB-INF/<servlet-name>-servlet.xml
2、<param-value>/WEB-INF/classes/springMVC.xml</param-value>
3、<param-value>classpath*:springMVC-mvc.xml</param-value>
4、多個值用逗號分隔
springMVC-mvc.xml 配置文件片段講解
<context:annotation-config/>
<!-- 自動掃描的包名 -->
<context:component-scan base-package="com.iflysse"/>
<!-- 默認的註解映射的支持 -->
<mvc:annotation-driven/>
<!-- 視圖解釋類 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/><!--可為空,方便實現自已的依據擴展名來選擇視圖解釋類的邏輯 -->
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
</bean>
<mvc:annotation-driven /> 是一種簡寫形式,完全可以手動配置替代這種簡寫形式,簡寫形式可以讓初學都快速應用默認配置方案。<mvc:annotation-driven /> 會自動注冊與 兩個bean,是spring MVC為@Controllers分發請求所必須的。
並提供了:數據綁定支持,@NumberFormatannotation支持,@DateTimeFormat支持,@Valid支持,讀寫XML的支持(JAXB),讀寫JSON的支持(Jackson)。
後面,我們處理響應ajax請求時,就使用到了對json的支持。
後面,對action寫JUnit單元測試時,要從spring IOC容器中取與 兩個bean,來完成測試,取的時候要知道是<mvc:annotation-driven />這一句注冊的這兩個bean。
<!-- json 支持 -->
<bean id=""
class="org.springframework.http.converter.json.">
<property name="objectMapper" ref="commonObjectMapper"/>
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
<!-- ObjectMapper json轉換 -->
<bean id="commonObjectMapper" class="cn.com.starit.util.CommonObjectMapper"/>
E. spring的xml配置文件的xml文件頭詳解
在spring的xml配置文件中,在頭部會出現如下的東西
這些奇怪的xmlns和很長的url的作用是什麼呢?
首先,介紹一下 xmlns 的作用,如下所示,一個 xml 文檔中如果包含如下兩種定義不同, 但是名稱相同的元素, xml 解析器是無法解析的, 因為它不能確定當你調用document.getElementsByTagName("book") 時應該返回哪個元素。
這時候可以通過在名稱增加前綴解決這個問題
由此,引入一個概念 命名空間 ,通過增加前綴表示不同的那是不同命名空間下的table,從而解決了矛盾,但是不同的人都有自己創建的不同的命名空間來描述同樣的東西,不利於xml文件信息的解析,比如說,同樣都是水果,可以從顏色和香味不同角度來定義成如下兩種形式:
為此,w3c(萬維網聯盟)對於一些類型,定義了對應的命名空間和這些類型的標准,xml解釋器碰到這些類型的時候就會通過這些標准去解析這類型的標簽,為了確保命名空間的唯一,所以不同的命名空間的通常使用URL作為被識別的id,如下例子:
這句話的作用是當前引入了一個叫做xsi的命名空間,xsi可以在接下來要使用該命名空間時所使用的,如下:
而 http://www.w3.org/2001/XMLSchema-instance 這個很長的字元串,則是xsi這個名稱空間被xml解釋器內部所識別的時候所真正使用的id,但也本身只是被當做一個字元串名字去處理,xml解釋器根據這個id去獲取它對應的標准,從而知道這個命名空間定義有什麼樣的標簽(xml解釋器自帶有一些通用的命名空間的標准),這個字元串雖然看起來是URL,但是和對應的網頁上的信息沒有關系,只是用來提供命名空間 唯一性 的作用,網址有時可以被打開,上面會有關於該命名空間的信息。
所以,spring配置文件中這三句話分別表示,引入了三個命名空間。
其中第一個xmlns後面沒有空間名的,表示引入了一個默認的名稱空間,下文中不使用命名空間前綴的都默認使用這個命名空間,這個默認的命名空間,其真正的id是 " http://www.springframework.org/schema/beans " 。
引入的第二個命名空間叫做xsi,其真正的id是 " http://www.w3.org/2001/XMLSchema-instance "
引入的第三個命名空間叫做context,其真正的id是 " http://www.springframework.org/schema/context "
在最後可以看到xsi:schemaLocation,這句話的意思表示使用命名空間xsi下的schemaLocatioin,設置了它對應的值為後面很多很多的URL,schemaLocation中存儲的值每兩個為一組, 第一個代表命名空間,第二個代表該命名空間的標準的文件位置 ,如下所示,這句話就是說明命名空間 http://www.springframework.org/schema/beans 的標准文件是 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd *
因為xml解釋器不一定含有所有命名空間的標准,通過這樣設置就可以告訴xml解釋器不同命名空間的對應的標準是什麼了,而這也是xsi這個命名空間的作用,要用到其schemaLocation。
最後,對應一般的xml解釋器的工作流程中,xml解釋器識別到有 「 http://www.w3.org/2001/XMLSchema-instance " 這個通用的名稱空間後,明白知道要引入一些不同命名空間,就會從其schemaLocation中獲取不同命名空間和其對應的標准。
F. SpringBoot 配置文件詳解(告別XML)
快速學會和掌握 SpringBoot 的 核心配置文件的使用。
SpringBoot 提供了豐富的 外部配置 ,常見的有:
其中核心配置文件我們並不陌生,主要以Key-Value的形式進行配置,其中屬性Key主要分為兩種:
在 application.properties 添加配置如下:
① 添加數據源信息
在 application.propertis 添加配置如下:
① 添加認證信息,其中 socks.indentity.* 是自定義的屬性前綴。
② 添加隨機值,其中spring.test.* 是自定義的屬性前綴。
使用方法: @ConfigurationProperties(prefix = "spring.datasource")
使用說明:提供 Setter方法 和 標記組件 Component
如何驗證是否成功讀取配置?答:這里可以簡單做個驗證,注入 MyDataSource ,使用 Debug 模式可以看到如下信息:
使用方法: @Value("spring.datasource.*")
使用說明:提供 Setter方法 和 標記組件 Component
注意事項:@Value不支持注入靜態變數,可間接通過Setter注入來實現。
關於兩者的簡單功能對比:
顯然,前者支持松綁定的特性更強大,所以在實際開發中建議使用@ConfigurationProperties來讀取自定義屬性。
SpringBoot 默認會載入這些路徑載入核心配置文件,按優先順序從高到低進行排列:具體規則詳見 ConfigFileApplicationListener
如果存在多個配置文件,則嚴格按照優先順序進行覆蓋,最高者勝出:
舉個簡單的例子,例如再上述位置都有一個application.properties ,並且每個文件都寫入了server.port=xx (xx分別是9001,9002,9003,9004),在啟動成功之後,最終應用的埠為:9004。圖例:
如果想修改默認的載入路徑 或者 調改默認的配置文件名,我們可以藉助命令行參數進行指定,例如:
YAML是JSON的一個超集,是一種可輕松定義層次結構的數據格式。
答: 因為配置文件這東西,結構化越早接觸越規范越好。這里推薦閱讀阮一峰老師寫的 YAML語言教程 ,寫的很簡單明了。
引入依賴: 在POM文件引入 snakeyaml 的依賴。
使用說明: 直接在類路徑添加 application.yml 即可。
例如下面這兩段配置是完全等價的:
① 在 application.yml 配置數據源:
② 在 application.properties 配置數據源:
在項目的實際開發中,我們往往需要根據不同的環境來載入不同的配置文件。例如生產環境,測試環境和開發環境等。此時,我們可以藉助 Profiles 來指定載入哪些配置文件。例如:
溫馨提示:如果spring.profiles.active指定了多個配置文件,則按順序載入,其中最後的優先順序最高,也就是最後的會覆蓋前者。
使用方法:
使用Maven插件打包好項目,然後在當前路徑,執行DOS命令: java -jar demo.jar --server.port=8081 ,在控制台可看到應用埠變成了8081。
實現原理:
默認情況下,SpringBoot會將這些命令行參數轉化成一個 Property ,並將其添加到 Environment 上下文。
溫馨提示:
由於命令行參數優先順序非常之高,基本高於所有常見的外部配置,所以使用的時候要謹慎。詳見 PropertySource 執行順序 。
關閉方法:
如果想禁用命令行屬性,可以設置如下操作:springApplication.setAddCommandLineProperties(false)