自動配置
SpringBoot啟動的時候加載主配置類(@SpringBootApplication注解修飾)宾巍, @SpringBootApplication開啟了自動配置功能 @EnableAutoConfiguration竟坛。
@EnableAutoConfiguration作用:利用AutoConfigurationImportSelector給spring容器中導(dǎo)入一些組件。
@SpringBootConfiguration作用:表示類提供springboot應(yīng)用功能丰包,繼@Configuration。
跟蹤一下AutoConfigurationImportSelector中的selectImports方法:
掃描所有jar包類路徑下 META-INF/spring.factories;
把掃描到的這些文件的內(nèi)容包裝成properties對象;
從properties中獲取到EnableAutoConfiguration.class類(類名)對應(yīng)的值壤巷,然后把他們 添加在容器中;
即將類路徑下META-INF/spring.factories里面配置的所有EnableAutoConfiguration的值加 入到了容器中邑彪。
這里,我們分析一下HttpEncodingAutoConfiguration胧华,其他類似:
@Configuration:
定義配置類寄症。
@EnableConfigurationProperties(HttpEncodingProperties.class):
啟動指定類的ConfigurationProperties功能;將配置文件中對應(yīng)的值和HttpEncodingProperties的屬性綁定起來矩动;并把HttpEncodingProperties加入到ioc容器有巧。
@ConditionalOnWebApplication:
判斷當(dāng)前應(yīng)用是否是web應(yīng)用,如果是悲没,當(dāng)前配置類 生效
@ConditionalOnClass(CharacterEncodingFilter.class):
判斷當(dāng)前項目有沒有這個類篮迎, CharacterEncodingFilter:SpringMVC中解決亂碼的過濾器。
@ConditionalOnProperty(prefix="spring.http.encoding",value="enabled"甜橱, matchIfMissing=true):
//判斷配置文件中是否存在某個配置spring.http.encoding.enabled享言;matchIfMissing表示,即使我們配置文件中不配置spring.http.encoding.enabled=true渗鬼,也是默認生效的览露;
@Conditional注解(Spring注解版):
條件注解,通過判斷類路徑下有沒有配置相應(yīng)jar包來確定是否加載和自動配置這個類譬胎。
所有在配置文件中能配置的屬性都是在xxxxProperties類中封裝的差牛,配置文件的配置項 就可以參照其對應(yīng)的這個屬性類,默認就是UTF-8編碼堰乔。
小結(jié):
1偏化、SpringBoot啟動會加載大量的自動配置類;
2镐侯、首先檢查SpringBoot默認的自動配置類是否滿足我們的需求侦讨;
3、具體查看這個自動配置類中配置了哪些組件苟翻;
4韵卤、給容器中的自動配置類添加組件的時候,會從properties類中獲取某些屬性崇猫。我們 就可以在配置文件中指定這些屬性的值沈条;
5、xxxxAutoConfigurartion:自動配置類诅炉,給容器中添加組件Bean蜡歹;xxxxProperties:封 裝配置文件中相關(guān)屬性;
Spring Boot提供了對應(yīng)用進行自動化配置涕烧。相比以前 XML 配置方式月而,很多顯式方式申 明是不需要的。二者议纯,大多數(shù)默認的配置足夠?qū)崿F(xiàn)開發(fā)功能父款,從而更快速開發(fā)。
application.properties添加debug=true痹扇,可以在控制臺查看自動配置報告信息铛漓。
拓展:@Conditional派生注解了解
核心:@Conditional指定的條件成立,才給容器中添加組件鲫构,配置類里面的所有內(nèi)容才 生效浓恶;即自動配置類必須在一定的條件下才能生效:
@ConditionalOnJava: 系統(tǒng)的java版本是否符合要求
@ConditionalOnBean: 容器中存在指定Bean;
@ConditionalOnMissingBean: 容器中不存在指定Bean结笨;
@ConditionalOnExpression: 滿足SpEL表達式指定
@ConditionalOnClass: 系統(tǒng)中有指定的類
@ConditionalOnMissingClass: 系統(tǒng)中沒有指定的類
@ConditionalOnSingleCandidate: 容器中只有一個指定的Bean包晰,或者這個Bean是首 選Bean
@ConditionalOnProperty: 系統(tǒng)中指定的屬性是否有指定的值
@ConditionalOnResource: 類路徑下是否存在指定資源文件
@ConditionalOnWebApplication: 當(dāng)前是web環(huán)境
@ConditionalOnNotWebApplication: 當(dāng)前不是web環(huán)境
自定義屬性(添加新屬性湿镀、覆蓋自動配置默認的屬性)
Spring Boot使用默認的全局的配置文件:application.properties 或 application.yml,配置文件名固定伐憾。
實例
1勉痴、建立PersonProperties
package com.javasgj.springboot.configuration;
import java.util.List;
import java.util.Map;
import javax.validation.constraints.Email;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
/**
* @Validated:對注入的值進行一些簡單的校驗;
* @Email 校驗郵箱地址
* @AssertFalse 校驗false
* @AssertTrue 校驗true
* @DecimalMax(value=,inclusive=) 小于等于value树肃,inclusive=true蒸矛,是小于等于
* @DecimalMin(value=,inclusive=) 與上類似
* @Max(value=) 小于等于value
* @Min(value=) 大于等于value
* @NotNull 檢查Null
* @Past 檢查日期
* @Pattern(regex=,flag=) 正則
* @Size(min=, max=) 字符串,集合胸嘴,map限制大小
* 這些注解位于javax.validation.constraints包下雏掠,校驗不通過時拋出異常。
* @Component:作為Bean注入到spring容器劣像,或者使用@Configuration乡话;
* @ConfigurationProperties:將配置文件中以person前綴的屬性值自動綁定到對應(yīng)的字段中;
*/
@Validated
@Component
@ConfigurationProperties(prefix="person")
public class PersonProperties {
private String id;
private String name;
private int age;
private String sex;
@Email
private String email;
private String desc;
private String desc1;
private Map<String, String> maps;
private List<String> list;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public String getDesc1() {
return desc1;
}
public void setDesc1(String desc1) {
this.desc1 = desc1;
}
public Map<String, String> getMaps() {
return maps;
}
public void setMaps(Map<String, String> maps) {
this.maps = maps;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
}
@ConfigurationProperties作用:默認加載classpath:application.properties或application.yml耳奕,如果同時存在則加載application.properties绑青,并且把文件中以person前綴的屬性值自動綁定到對應(yīng)的l字段中。
當(dāng)然如果是自定義屬性值屋群,也可以使用@PropertySource指定屬性文件闸婴。
但是要覆蓋框架自動配置的屬性,只能使用默認的全局配置文件谓晌。
2掠拳、src/main/resources下建立:application.properties
#properties癞揉、yml同時存在纸肉,取properties內(nèi)容
#調(diào)試信息,控制臺查看自動配置報告信息
#debug=true
#自定義屬性
person.name=Jim
person.age=28
person.sex=0
person.email=111@qq.com
#${}占位符喊熟,可以引用配置文件其他屬性值柏肪,如果沒有可以配置一個默認值:${person.name:default}
person.desc=I'm ${person.name}
#\n特殊字符,換行
person.desc1=I'm ${person.name} \n welcome!
#map數(shù)據(jù)類型芥牌,對象類型同理:person.對象名.屬性名
person.maps.privince=js
person.maps.city=nj
#array烦味、list、set集合
person.list[0]=0
person.list[1]=1
#隨機數(shù)壁拉,通過 RandomValuePropertySource工具類谬俄。可以生成隨機字符串弃理、隨機 int 溃论、隨機 long、某范圍的隨機數(shù)
#person.id=${random.int}
#person.id=${random.long}
#person.id=${random.long[1,100]}
#person.id=${random.uuid}
person.id=${random.value}
或者使用application.yml
person:
name: jim1
age: 28
sex: 0
desc1: I am jim \n welcome!
list: [0,1,2]
person.maps: {privince: js, city: nj}
注意:
1痘昌、yml格式冒號后面都要一個空格钥勋,屬性前面也只能添加一個空格炬转,可以使用在線編 輯yml(http://www.bejson.com/validators/yaml_editor/),有校驗格式功能算灸。
2扼劈、單引號:轉(zhuǎn)義特殊字符,特殊字符只是一個普通的字符串?dāng)?shù)據(jù)菲驴,等同于沒有引號
name: ‘zhangsan \n lisi’ 輸出:zhangsan \n lisi
3荐吵、雙引號:不會轉(zhuǎn)義字符串里面的特殊字符,特殊字符會作為本身想表示的意思
name: "zhangsan \n lisi" 輸出:zhangsan
lisi
3赊瞬、應(yīng)用啟動類
package com.javasgj.springboot.configuration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* spring boot應(yīng)用啟動類
*/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
4捍靠、編寫測試類
pom.xml引入依賴
<!-- spring boot test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
PersonPropertiesTest:
package com.javasgj.springboot.configuration;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes=Application.class)
public class PersonPropertiesTest {
@Autowired
PersonProperties personProperties;
@Test
public void testGetName() {
/**
* springboot默認以ISO-8859-1編碼讀取properties文件內(nèi)容,所以會有中文亂碼森逮,我們可以做如下處理解決亂碼榨婆,
* 或者使用yml類型文件進行配置,沒有中文亂碼問題褒侧。
*/
/*try {
System.out.println(new String(personProperties.getName().getBytes("ISO-8859-1"), "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}*/
System.out.println("結(jié)果:" + personProperties.getId());
System.out.println("結(jié)果:" + personProperties.getName());
System.out.println("結(jié)果:" + personProperties.getEmail());
System.out.println("結(jié)果:" + personProperties.getDesc1());
System.out.println("結(jié)果:" + personProperties.getMaps().keySet().toString());
System.out.println("結(jié)果:" + personProperties.getList().size());
}
}
@SpringBootTest指定應(yīng)用啟動類Application
趕緊運行結(jié)果看看吧良风!
擴展:
Spring Boot不單單從application.properties獲取配置,我們可以在程序中設(shè)置多種 配置屬性闷供。按照以下列表的優(yōu)先級從高到低排列:
1烟央、命令行參數(shù)
2、java:comp/env 里的 JNDI 屬性
3歪脏、JVM 系統(tǒng)屬性
4疑俭、操作系統(tǒng)環(huán)境變量
5、RandomValuePropertySource 屬性類生成的 random.* 屬性
6婿失、應(yīng)用外部的application-{profile}.properties或application.yml(帶spring.profile)文件
7钞艇、應(yīng)用內(nèi)部的application-{profile}.properties或application.yml(帶spring.profile)文件
6、應(yīng)用以外的 application.properties(或 yml)文件
7豪硅、應(yīng)用內(nèi)部的 application.properties(或 yml)文件
8哩照、在應(yīng)用 @Configuration 配置類中,用 @PropertySource 注解聲明的屬性文件
9懒浮、SpringApplication.setDefaultProperties 聲明的默認屬性
注意一些特殊屬性如:user.name飘弧,如果你在配置文件配置了此屬性,但是確獲取不到 配置文件中的值砚著,為什么呢次伶?因為系統(tǒng)屬性有user.name,優(yōu)先級又高稽穆,會獲取到機器 當(dāng)前用戶賬號冠王。