springboot:框架想學好,屬性配置和使用你都明白了嗎?
在昨天介紹springboot框架之後,大家對於這個框架的熱度還是不錯。那麼今天Damon繼續更大家介紹下關於springboot更深入的東西。希望能夠幫助大家成長以及進步。如果想要了解昨天的文章,可以去github或者翻閱下此前的紀錄都能夠看到。
Spring Boot 屬性配置和使用
- 簡單的說,Spring Boot 就是允許通過外部配置讓你在不同的環境使用同一應用程式的程式碼,或許說就是可以通過配置檔案來注入屬性或者修改預設的配置。
Spring Boot 支援多種外部配置方式
這些方式優先順序如下:
-
- 命令列引數
-
- 來自java:comp/env的JNDI屬性
-
- Java系統屬性(System.getProperties())
-
- 作業系統環境變數
-
- RandomValuePropertySource配置的random.*屬性值
-
- jar包外部的application-{profile}.properties或application.yml(帶spring.profile)配置檔案
-
- jar包內部的application-{profile}.properties或application.yml(帶spring.profile)配置檔案
-
- jar包外部的application.properties或application.yml(不帶spring.profile)配置檔案
-
- jar包內部的application.properties或application.yml(不帶spring.profile)配置檔案
-
- @Configuration註解類上的@PropertySource
-
- 通過SpringApplication.setDefaultProperties指定的預設屬性
命令列引數
-
通過java -jar app.jar --name="Spring" --server.port=9090方式來傳遞引數。
-
引數用--xxx=xxx的形式傳遞。
-
可以使用的引數可以是我們自己定義的,也可以是Spring Boot中預設的引數。 -很多人可能會關心如web埠如何配置這樣的問題,這些都是Spring Boot中提供的引數,部分可用引數如下:
# LOGGING logging.path=/var/logs logging.file=myapp.log logging.config= # location of config file (default classpath:logback.xml for logback) logging.level.*= # levels for loggers,e.g. "logging.level.org.springframework=DEBUG" (TRACE,DEBUG,INFO,WARN,ERROR,FATAL,OFF) # EMBEDDED SERVER CONFIGURATION (ServerProperties) server.port=8080 server.address= # bind to a specific NIC server.session-timeout= # session timeout in seconds server.context-parameters.*= # Servlet context init parameters,e.g. server.context-parameters.a=alpha server.context-path= # the context path,defaults to '/' server.servlet-path= # the servlet path,defaults to '/' 複製程式碼
- 注意:命令列引數在app.jar的後面!
- 可以通過SpringApplication.setAddCommandLineProperties(false)禁用命令列配置。
作業系統環境變數
- 配置過JAVA_HOME的應該都瞭解這一個。
- 這裡需要注意的地方,有些OS可以不支援使用.這種名字,如server.port,這種情況可以使用SERVER_PORT來配置。
應用配置檔案(.properties或.yml)
-
在配置檔案中直接寫: name=Isea533 server.port=8080
-
.yml格式的配置檔案如: name: Isea533 server: port: 8080
-
當有字首的情況下,使用.yml格式的配置檔案更簡單。關於.yml配置檔案用法請看這裡
-
注意:使用.yml時,屬性名的值和冒號中間必須有空格,如name: Isea533正確,name:Isea533就是錯的。
屬性配置檔案的位置
- spring會從classpath下的/config目錄或者classpath的根目錄查詢application.properties或application.yml。
- /config優先於classpath根目錄
@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); 複製程式碼
應用(使用)屬性
@Value(“${xxx}”)
- 這種方式是最簡單的,通過@Value註解可以將屬性值注入進來。
@ConfigurationProperties
-
Spring Boot 可以方便的將屬性注入到一個配置物件中。例如:
my.name=Isea533 my.port=8080 my.servers[0]=dev.bar.com my.servers[1]=foo.bar.com 複製程式碼
-
對應物件:
@ConfigurationProperties(prefix="my") public class Config { private String name; private Integer port; private List<String> servers = new ArrayList<String>(); public String geName(){ return this.name; } public Integer gePort(){ return this.port; } public List<String> getServers() { return this.servers; } } 複製程式碼
-
Spring Boot 會自動將prefix="my"字首為my的屬性注入進來。
-
Spring Boot 會自動轉換型別,當使用List的時候需要注意在配置中對List進行初始化!
-
Spring Boot 還支援巢狀屬性注入,例如: name=isea533 jdbc.username=root jdbc.password=root ...
-
對應的配置類:
-
@ConfigurationProperties public class Config { private String name; private Jdbc jdbc; class Jdbc { private String username; private String password; //getter... } public Integer gePort(){ return this.port; } public Jdbc getJdbc() { return this.jdbc; } 複製程式碼
}
-
jdbc開頭的屬性都會注入到Jdbc物件中。
在@Bean方法上使用@ConfigurationProperties
- 例如: @ConfigurationProperties(prefix = "foo") @Bean public FooComponent fooComponent() { ... }
- Spring Boot 會將foo開頭的屬性按照名字匹配注入到FooComponent物件中。
- 這種方式比較少見,我們在整合mybatis那章結合Druid的配置來具體演示。
屬性佔位符
-
例如: 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預設的${}方式改為了@ @方式,例如@name@。
-
如果你是引入的Spring Boot,你可以修改使用其他的分隔符
通過屬性佔位符還能縮短“命令列”引數
- 例如修改web預設埠需要使用--server.port=9090方式,如果在配置中寫上: server.port=${port:8080}
- 那麼就可以使用更短的--port=9090,當不提供該引數的時候使用預設值8080。
屬性名匹配規則
-
例如有如下配置物件:
@Component @ConfigurationProperties(prefix="person") public class ConnectionSettings { private String firstName; } 複製程式碼
- firstName可以使用的屬性名如下:
- person.firstName,標準的駝峰式命名
- person.first-name,虛線(-)分割方式,推薦在.properties和.yml配置檔案中使用
- PERSON_FIRST_NAME,大寫下劃線形式,建議在系統環境變數中使用
屬性驗證
-
可以使用JSR-303註解進行驗證,例如:
@Component @ConfigurationProperties(prefix="connection") public class ConnectionSettings { @NotNull private InetAddress remoteAddress; // ... getters and setters } 複製程式碼