1. 程式人生 > >Spring boot 2 -配置詳解

Spring boot 2 -配置詳解

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

1、自動化配置

     Spring Boot 對於開發人員最大的好處在於可以對 Spring 應用進行自動配置。Spring Boot 會根據應用中宣告的第三方依賴來自動配置 Spring 框架,而不需要進行顯式的宣告。比如當聲明瞭對 HSQLDB 的依賴時,Spring Boot 會自動配置成使用 HSQLDB 進行資料庫操作。

Spring Boot 推薦採用基於 Java 註解的配置方式,而不是傳統的 XML。只需要在主配置 Java 類上新增“@EnableAutoConfiguration”註解就可以啟用自動配置。Spring Boot 的自動配置功能是沒有侵入性的,只是作為一種基本的預設實現。開發人員可以通過定義其他 bean 來替代自動配置所提供的功能。比如當應用中定義了自己的資料來源 bean 時,自動配置所提供的 HSQLDB 就不會生效。這給予了開發人員很大的靈活性。既可以快速的建立一個可以立即執行的原型應用,又可以不斷的修改和調整以適應應用開發在不同階段的需要。可能在應用最開始的時候,嵌入式的記憶體資料庫(如 HSQLDB)就足夠了,在後期則需要換成 MySQL 等資料庫。Spring Boot 使得這樣的切換變得很簡單。

2、外部化的配置

     在應用中管理配置並不是一個容易的任務,尤其是在應用需要部署到多個環境中時。通常會需要為每個環境提供一個對應的屬性檔案,用來配置各自的資料庫連線資訊、伺服器資訊和第三方服務賬號等。通常的應用部署會包含開發、測試和生產等若干個環境。不同的環境之間的配置存在覆蓋關係。測試環境中的配置會覆蓋開發環境,而生產環境中的配置會覆蓋測試環境。Spring 框架本身提供了多種的方式來管理配置屬性檔案。Spring 3.1 之前可以使用 PropertyPlaceholderConfigurer。Spring 3.1 引入了新的環境(Environment)和概要資訊(Profile)API,是一種更加靈活的處理不同環境和配置檔案的方式。不過 Spring 這些配置管理方式的問題在於選擇太多,讓開發人員無所適從。Spring Boot 提供了一種統一的方式來管理應用的配置,允許開發人員使用屬性檔案、YAML 檔案、環境變數和命令列引數來定義優先順序不同的配置值。

      Spring Boot 所提供的配置優先順序順序比較複雜。按照優先順序從高到低的順序,具體的列表如下所示。

  1. 命令列引數。
  2. 通過 System.getProperties() 獲取的 Java 系統引數。
  3. 作業系統環境變數。
  4. 從 java:comp/env 得到的 JNDI 屬性。
  5. 通過 RandomValuePropertySource 生成的“random.*”屬性。
  6. 應用 Jar 檔案之外的屬性檔案。
  7. 應用 Jar 檔案內部的屬性檔案。
  8. 在應用配置 Java 類(包含“@Configuration”註解的 Java 類)中通過“@PropertySource”註解宣告的屬性檔案。
  9. 通過“SpringApplication.setDefaultProperties”宣告的預設屬性。

        Spring Boot 的這個配置優先順序看似複雜,其實是很合理的。比如命令列引數的優先順序被設定為最高。這樣的好處是可以在測試或生產環境中快速地修改配置引數值,而不需要重新打包和部署應用。


命令列引數

通過Java -jar app.jar --name="Spring" --server.port=9090方式來傳遞引數。

SpringApplication 類預設會把以“--”開頭的命令列引數轉化成應用中可以使用的配置引數,如 “--name=Alex” 會設定配置引數 “name” 的值為 “Alex”.

可以使用的引數可以是我們自己定義的,也可以是Spring Boot中預設的引數。

注意:命令列引數在app.jar的後面!

可以通過SpringApplication.setAddCommandLineProperties(false)禁用命令列配置。

Java系統屬性

注意Java系統屬性位置java -Dname="isea533" -jar app.jar,可以配置的屬性都是一樣的,優先順序不同。

例如java -Dname="isea533" -jar app.jar --name="Spring!"name值為Spring.

      有些系統,關於一些資料庫或其他第三方賬戶等資訊,由於安全問題,其配置並不會提前配置在專案中暴露給開發人員。 
      對於這種情況,我們在執行程式的時候,可以通過引數指定一個外部配置檔案。 
       以 demo.jar 為例,方法如下: java -jar demo.jar --spring.config.location=/opt/config/application.properties

      其中檔名隨便定義,無固定要求。

RandomValuePropertySource 

      RandomValuePropertySource 可以用來生成測試所需要的各種不同型別的隨機值,從而免去了在程式碼中生成的麻煩。RandomValuePropertySource 可以生成數字和字串。數字的型別包含 int 和 long,可以限定數字的大小範圍。以“random.”作為字首的配置屬性名稱由 RandomValuePropertySource 來生成:

 系統中用到隨機數的地方,例如 使用 RandomValuePropertySource 生成的配置屬性:
user.id=${random.value}user.count=${random.int}user.max=${random.long}user.number=${random.int(100)}user.range=${random.int[100, 1000]

random.int*支援value引數和,max引數,當提供max引數的時候,value就是最小值

3、屬性檔案

3.1 屬性配置檔案的位置

      屬性檔案是最常見的管理配置屬性的方式。Spring Boot 提供的 SpringApplication 類會搜尋並載入 application.properties 或application.yml檔案來獲取配置屬性值。SpringApplication 類會在下面位置搜尋該檔案。

  • 當前目錄的“/config”子目錄。
  • 當前目錄。
  • classpath 中的“/config”包。
  • classpath

     上面的順序也表示了該位置上包含的屬性檔案的優先順序。優先順序按照從高到低的順序排列。  即:/config優先於classpath根目錄

      可以通過“spring.config.name”配置屬性來指定不同的屬性檔名稱。也可以通過“spring.config.location”來新增額外的屬性檔案的搜尋路徑。如果應用中包含多個 profile,可以為每個 profile 定義各自的屬性檔案,按照“application-{profile}”來命名。


3.2應用配置檔案(.properties或.yml)

     在配置檔案application.properties 中直接寫:
name=Isea533
server.port=8080


    .yml格式的配置檔案如:
name: Isea533
server:
    port: 8080

當有字首的情況下,使用.yml格式的配置檔案更簡單。關於.yml配置檔案用法請看這裡

注意:使用.yml時,屬性名的值和冒號中間必須有空格,如name: Isea533正確,name:Isea533就是錯的。

3.3 @PropertySource優先順序比較

這個註解可以指定具體的屬性配置檔案,優先順序比較低。

SpringApplication.setDefaultProperties

例如:

SpringApplication application = new SpringApplication(Application.class);Map<String, Object> defaultMap = new HashMap<String, Object>();defaultMap.put("name", "Isea-Blog");//還可以是Properties物件application.setDefaultProperties(defaultMap);application.run(args);

3.5 應用程式使用屬性@Value(“${xxx}”)

對於配置屬性,可以在程式碼中通過“@Value”來使用,如:

@[email protected] class Application { @Value("${name}") private String name; @RequestMapping("/") String home() { return String.format("Hello %s!", name); }}

變數 name 的值來自配置屬性中的“name”屬性。

比如application.properties有 port=8081 

@Value("${port:8082}")
private String port;

即可獲取8081這個值


3.6屬性佔位符


例如:

app.name=MyApp
app.description=${app.name} is a Spring Boot application

可以在配置檔案中引用前面配置過的屬性(優先順序前面配置過的這裡都能用)。

通過如${app.name:預設名稱}方法還可以設定預設值,當找不到引用的屬性時,會使用預設的屬性。

由於${}方式會被Maven處理。如果你pom繼承的spring-boot-starter-parent,Spring Boot 已經將maven-resources-plugins預設的${}方式改為了@ @方式,例如@[email protected]

如果你是引入的Spring Boot,你可以修改使用其他的分隔符

3.7通過屬性佔位符還能縮短命令引數


例如修改web預設埠需要使用--server.port=9090方式,如果在配置中寫上:

server.port=${port:8080}

那麼就可以使用更短的--port=9090,當不提供該引數的時候使用預設值8080。

3.8屬性名匹配規則


例如有如下配置物件:

@Component@ConfigurationProperties(prefix="person")public class ConnectionSettings {    private String firstName;}

firstName可以使用的屬性名如下:

person.firstName,標準的駝峰式命名
person.first-name,虛線(-)分割方式,推薦在.properties和.yml配置檔案中使用
PERSON_FIRST_NAME,大寫下劃線形式,建議在系統環境變數中使用

3.9屬性驗證

可以使用JSR-303註解進行驗證,例如:

@Component@ConfigurationProperties(prefix="connection")public class ConnectionSettings {    @NotNull    private InetAddress remoteAddress;    // ... getters and setters}

4、自定義配置

   spring boot使用application.properties默認了很多配置。但需要自己新增一些配置的時候,我們應該怎麼做呢。

若繼續在application.properties中新增

如:

wisely2.name=wyf2  wisely2.gender=male2  


定義配置類:

@ConfigurationProperties(prefix = "wisely2"public class Wisely2Settings {      private String name;      private String gender;      public String getName() {          return name;      }      public void setName(String name) {          this.name = name;      }      public String getGender() {          return gender;      }      public void setGender(String gender) {          this.gender = gender;      }    }  


若新用新的配置檔案

如我新建一個wisely.properties

wisely.name=wangyunfei  wisely.gender=male 


 需定義如下配置類

@ConfigurationProperties(prefix = "wisely",locations = "classpath:config/wisely.properties"public class WiselySettings {      private String name;      private String gender;      public String getName() {          return name;      }      public void setName(String name) {          this.name = name;      }      public String getGender() {          return gender;      }      public void setGender(String gender) {          this.gender = gender;      }    } 

最後注意在spring Boot入口類加上@EnableConfigurationProperties
@SpringBootApplication  
@EnableConfigurationProperties({WiselySettings.class,Wisely2Settings.class})  
public class DemoApplication {  
  
    public static void main(String[] args) {  
        SpringApplication.run(DemoApplication.class, args);  
    }  
}  

  

使用定義的properties

在別的bean中可直接注入

@Controller  public class TestController {      @Autowired      WiselySettings wiselySettings;      @Autowired      Wisely2Settings wisely2Settings;        @RequestMapping("/test")      public @ResponseBody String test(){          System.out.println(wiselySettings.getGender()+"---"+wiselySettings.getName());          System.out.println(wisely2Settings.getGender()+"==="+wisely2Settings.getGender());          return "ok";      }   }  
或者

在@Bean方法上使用@ConfigurationProperties
例如:

@ConfigurationProperties(prefix = "foo")@Beanpublic FooComponent fooComponent() {    ...}
Spring Boot 會將foo開頭的屬性按照名字匹配注入到FooComponent物件中。



涉及四個檔案:

1:properties檔案,這裡是config.properties,放置在properties檔案常放置的地方,即src/main/resources目錄下

2:一個存放properties配置檔案屬性的Bean,這裡是WiselySettings.Java

4:在spring Boot入口類加上@EnableConfigurationProperties

3:讀取配置的Controller或者bean



5、YAML配置

相對於屬性檔案來說,YAML 是一個更好的配置檔案格式。YAML 在 Ruby on Rails 中得到了很好的應用。SpringApplication 類也提供了對 YAML 配置檔案的支援,只需要新增對 SnakeYAML 的依賴即可。application.yml 檔案的示例。

spring: profiles: developmentdb: url: jdbc:hsqldb:file:testdb username: sa password:---spring: profiles: testdb: url: jdbc:mysql://localhost/test username: test password: test

AML 檔案同時給出了 development 和 test 兩個不同的 profile 的配置資訊,這也是 YAML 檔案相對於屬性檔案的優勢之一。除了使用“@Value”註解繫結配置屬性值之外,還可以使用更加靈活的方式。YAML 檔案的 Java 類:

@[email protected](prefix="db")public class DBSettings { private String url; private String username; private String password;}

     通過“@ConfigurationProperties(prefix="db")”註解,配置屬性中以“db”為字首的屬性值會被自動繫結到 Java 類中同名的域上,如 url 域的值會對應屬性“db.url”的值。只需要在應用的配置類中新增“@EnableConfigurationProperties”註解就可以啟用該自動繫結功能。





6. @EnableAutoCongiguration配置

從Spring 3.0開始,為了替代繁瑣的XML配置,引入了@Enable...註解對@Configuration類進行修飾以達到和XML配置相同的效果。想必不少開發者已經使用過類似註解:

  • @EnableTransactionManagement開啟Spring事務管理,相當於XMl中的<tx:*>
  • @EnableWebMvc使用Spring MVC框架的一些預設配置
  • @EnableScheduling會初始化一個Scheduler用於執行定時任務和非同步任務

Spring Boot提供的@EnableAutoCongiguration似乎功能更加強大,一旦加上,上述所有的配置似乎都被包含進來而無需開發者顯式宣告。它究竟是如何做到的呢,先看看它的定義:

@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Import({ EnableAutoConfigurationImportSelector.class,        AutoConfigurationPackages.Registrar.class })public @interface EnableAutoConfiguration {    /**     * Exclude specific auto-configuration classes such that they will never be applied.     */    Class<?>[] exclude() default {};}

EnableAutoConfigurationImportSelector使用的是spring-core模組中的SpringFactoriesLoader#loadFactoryNames()方法,它的作用是在類路徑上掃描META-INF/spring.factories檔案中定義的類:

# Initializersorg.springframework.context.ApplicationContextInitializer=\org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer# Auto Configureorg.springframework.boot.autoconfigure.EnableAutoConfiguration=\org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration,\org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration,\org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\org.springframework.boot.autoconfigure.data.JpaRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.MongoRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.redis.RedisAutoConfiguration,\org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\org.springframework.boot.autoconfigure.jms.JmsTemplateAutoConfiguration,\org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\org.springframework.boot.autoconfigure.mongo.MongoTemplateAutoConfiguration,\org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,\org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,\org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,\org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,\org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,\org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration,\org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,\org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration,\org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration

實際上這就是Spring Boot會自動配置的一些物件,例如前面提到的Web框架由EmbeddedServletContainerAutoConfiguration,DispatcherServletAutoConfigurationServerPropertiesAutoConfiguration等配置完成,而DataSource的自動配置則是由DataSourceAutoConfiguration完成。現在我們以Mongo的配置MongoAutoConfiguration為例,來探索Spring Boot是如何完成這些配置的:

@Configuration@ConditionalOnClass(Mongo.class)@EnableConfigurationProperties(MongoProperties.class)public class MongoAutoConfiguration {    @Autowired    private MongoProperties properties;    private Mongo mongo;    @PreDestroy    public void close() throws UnknownHostException {        if (this.mongo != null) {            this.mongo.close();        }    }    @Bean    @ConditionalOnMissingBean    public Mongo mongo() throws UnknownHostException {        this.mongo = this.properties.createMongoClient();        return this.mongo;    }}

      首先這是一個Spring的配置@Configuration,它定義了我們訪問Mongo需要的@Bean,如果這個@Configuration被Spring Context掃描到,那麼Context中自然也就有兩個一個Mongo物件能夠直接為開發者所用。

但是注意到其它幾個Spring註解:

  • @ConditionOnClass表明該@Configuration僅僅在一定條件下才會被載入,這裡的條件是Mongo.class位於類路徑上
  • @EnableConfigurationProperties將Spring Boot的配置檔案(application.properties)中的spring.data.mongodb.*屬性對映為MongoProperties並注入到MongoAutoConfiguration中。
  • @ConditionalOnMissingBean說明Spring Boot僅僅在當前上下文中不存在Mongo物件時,才會例項化一個Bean。這個邏輯也體現了Spring Boot的另外一個特性——自定義的Bean優先於框架的預設配置,我們如果顯式的在業務程式碼中定義了一個Mongo物件,那麼Spring Boot就不再建立。

接下來看一看MongoProperties

@ConfigurationProperties(prefix = "spring.data.mongodb")public class MongoProperties {    private String host;    private int port = DBPort.PORT;    private String uri = "mongodb://localhost/test";    private String database;    // ... getters/ setters omitted}

顯然,它就是以spring.data.mongodb作為字首的屬性,然後通過名字直接對映為物件的屬性,同時還包含了一些預設值。如果不配置,那麼mongo.uri就是mongodb://localhost/test


配置通用屬性

Spring Boot application.propertis配置檔案的相關通用屬性

Spring Boot application.yaml配置檔案的相關通用屬性





感謝您的支援,我會繼續努力的! 掃碼打賞,你說多少就多少

         
           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述