springboot項目中有兩種配置文件 bootstrap 和 applicationgit
bootstrap是應用程序的父上下文,由父Spring ApplicationContext加載。因此加載順序優先於application。web
bootstrap 裏面的屬性不能被覆蓋。spring
spring: application: name: @artifactId@ cloud: nacos: discovery: server-addr: nacoshost:8848 config: server-addr: ${spring.cloud.nacos.discovery.server-addr} file-extension: yml shared-dataids: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension} autoconfigure: exclude: org.springframework.cloud.gateway.config.GatewayAutoConfiguration,org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration profiles: active: @profiles.active@
這段是配置文件內容:@artifactId@ 能夠定位到pom 文件中的 <artifactId>pipe-server</artifactId>bootstrap
@profiles.active@ 能夠定位到pom文件中的 <profiles.active>test</profiles.active>springboot
server-addr: ${spring.cloud.nacos.discovery.server-addr}
這種寫法 ${}定位的值就是本yml文件:server-addr: nacoshost:8848 這個地方
把外部連接地址放在bootstrap 文件裏面 而後去讀取文件 外部文件或者在服務器上,或者在git 經過nacos、spring cloud config、apollo 等等去找到外部文件而後讀取。服務器
profile是Spring對不一樣環境提供不一樣配置功能的支持,能夠經過激活不一樣的環境版本,實現快速切換環境;在主配置文件編寫的時候,文件名能夠是 application-{profile}.properties/yml , 用來指定多個環境版本;app
例如:application-test.properties 表明測試環境配置 application-dev.properties 表明開發環境配置,可是Springboot並不會直接啓動這些配置文件,它默認使用application.properties主配置文件;dom
咱們須要經過一個配置來選擇須要激活的環境:在bootstrap中使用:spring.profiles.active=devide
寫個yml文件:測試
anything: isok: true sout: im.peizhi.wenjian
/* @ConfigurationProperties做用: 將配置文件中配置的每個屬性的值,映射到這個組件中; 告訴SpringBoot將本類中的全部屬性和配置文件中相關的配置進行綁定 參數 prefix = 「person」 : 將配置文件中的person下面的全部屬性一一對應 只有這個組件是容器中的組件,才能使用容器提供的@ConfigurationProperties功能 */ @Component //註冊bean @ConfigurationProperties(prefix = "anything") public class Anything{ private Boolean isok;
private String sout ; }
除了@ConfigurationProperties之外還可使用@Value進行讀取:
@Component //註冊bean public class Person { //直接使用@value @Value("${anything.isok}") //從配置文件中取值
private Boolean isok;
@ConfigurationProperties是支持鬆散綁定的 鬆散綁定:好比個人yml中寫的last-name,這個和lastName是同樣的, - 後面跟着的字母默認是大寫的。這就是鬆散綁定 ,@Value 不支持
@Value的其餘使用方法:應該能夠猜的看懂吧 不贅述了
@Component("role2") public class Role2 { //賦值long型 @Value("#{2}") private Long id; //字符串賦值 @Value("#{'role_name_2'}") private String roleName; //字符串賦值 @Value("#{'note_2'}") private String note; }
@Component("elBean") public class ElBean { //經過beanName獲取bean,而後注入 @Value("#{role2}") private Role2 role2; //獲取bean的屬性id @Value("#{role2.id}") private Long id; //調用bean的getNote方法,獲取角色名稱 // @Value("#{role.getNote().toString()}") @Value("#{role2.getNote()?.toString()}") private String note; @Value("#{T(Math).PI}") private double pi; @Value("#{T(Math).random()}") private double random; @Value("#{role.id+1}") private int num; }
@PropertySource :加載指定的配置文件;
@PropertySource(value = "classpath:bootstrap.yml") @Component //註冊bean public class Anything{ @Value("${anything.isok}") private String name; }
1.SpringBoot啓動的時候加載主配置類,開啓自動配置功能@EnableAutoConfig
2.@EnableAutoConfig做用:
這裏裏面有一個 SpringFactoriesLoader.loadFactoryNames() ,咱們繼續進去看 , 它又調用了 loadSpringFactories 方法;繼續跟蹤。發現它去得到了一個資源文件:"META-INF/spring.factories"
繼續閱讀源碼 , 它將讀取到的資源封裝在url中,而後遍歷url , 將這些url文件封裝在Properties文件中;最後返回封裝好的結果;他的那個ClassLoader參數,咱們追蹤回去,看到他就是 EnableAutoConfiguration ;
說明了這個邏輯就是 從properties中獲取到EnableAutoConfiguration.class類(類名)對應的值,而後把他們添加在容器中
3.每個自動配置類能夠進行自動配置功能;
4.咱們
@ConfigurationProperties( prefix = "spring.http" ) //從配置文件中獲取指定的值和bean的屬性進行綁定 在一次工做中個人書寫是這樣的(prefix = "tlyh.restUrl")報錯格式不規範 應該改成:tlyh.rest-url public class HttpProperties { private boolean logRequestDetails; private final HttpProperties.Encoding encoding = new HttpProperties.Encoding(); public HttpProperties() { } public boolean isLogRequestDetails() { return this.logRequestDetails; } public void setLogRequestDetails(boolean logRequestDetails) { this.logRequestDetails = logRequestDetails; } public HttpProperties.Encoding getEncoding() { return this.encoding; } public static class Encoding { public static final Charset DEFAULT_CHARSET; private Charset charset; private Boolean force; private Boolean forceRequest; private Boolean forceResponse; private Map<Locale, Charset> mapping; } }
5. 下面是本身寫的組件
@Configuration //表示這是一個配置類,之前編寫的配置文件同樣,也能夠給容器中添加組件 //啓動指定類的ConfigurationProperties功能; //進入這個HttpProperties查看,將配置文件中對應的值和HttpProperties綁定起來; //並把HttpProperties加入到ioc容器中 @EnableConfigurationProperties({HttpProperties.class}) //Spring底層@Conditional註解 //根據不一樣的條件判斷,若是知足指定的條件,整個配置類裏面的配置就會生效; //這裏的意思就是判斷當前應用是不是web應用,若是是,當前配置類生效 @ConditionalOnWebApplication( type = Type.SERVLET ) //判斷當前項目有沒有這個類CharacterEncodingFilter;SpringMVC中進行亂碼解決的過濾器; @ConditionalOnClass({CharacterEncodingFilter.class}) //判斷配置文件中是否存在某個配置:spring.http.encoding.enabled; //若是不存在,判斷也是成立的 //即便咱們配置文件中不配置pring.http.encoding.enabled=true,也是默認生效的; @ConditionalOnProperty( prefix = "spring.http.encoding", value = {"enabled"}, matchIfMissing = true ) public class HttpEncodingAutoConfiguration { //他已經和SpringBoot的配置文件映射了 private final Encoding properties; //只有一個有參構造器的狀況下,參數的值就會從容器中拿 public HttpEncodingAutoConfiguration(HttpProperties properties) { this.properties = properties.getEncoding(); } //給容器中添加一個組件,這個組件的某些值須要從properties中獲取 @Bean @ConditionalOnMissingBean //判斷容器沒有這個組件? public CharacterEncodingFilter characterEncodingFilter() { CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter(); filter.setEncoding(this.properties.getCharset().name()); filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST)); filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE)); return filter; } }
一句話總結 : 根據當前不一樣的條件判斷,決定這個配置類是否生效!
一但這個配置類生效;這個配置類就會給容器中添加各類組件;這些組件的屬性是從對應的properties類中獲取的,這些類裏面的每個屬性又是和配置文件綁定的;
這就是自動裝配的原理!
1)、SpringBoot啓動會加載大量的自動配置類
2)、咱們看咱們須要的功能有沒有在SpringBoot默認寫好的自動配置類當中;
3)、咱們再來看這個自動配置類中到底配置了哪些組件;(只要咱們要用的組件存在在其中,咱們就不須要再手動配置了)
4)、給容器中自動配置類添加組件的時候,會從properties類中獲取某些屬性。咱們只須要在配置文件中指定這些屬性的值便可;
xxxxAutoConfigurartion:自動配置類;給容器中添加組件
瞭解完自動裝配的原理後,咱們來關注一個細節問題 ,自動配置類必須在必定的條件下才能生效;
做用:必須是@Conditional指定的條件成立,纔給容器中添加組件,配置配裏面的全部內容才生效;
那麼多的自動配置類,必須在必定的條件下才能生效;也就是說,咱們加載了這麼多的配置類,但不是全部的都生效了。
咱們怎麼知道哪些自動配置類生效;咱們能夠經過啓用 debug=true屬性;來讓控制檯打印自動配置報告,這樣咱們就能夠很方便的知道哪些自動配置類生效;