spring boot支持properties和yaml兩種配置格式,properties在spring項目中很常見,key value形式配置參數,而yaml 是一種通用的數據串行化格式,專門用來寫配置文件的語言,比 JSON 格式方便,支持對象、數組、純量三種數據結構。建議在spring boot項目中採用yaml方式,讓配置結構更加清晰。
1.配置與使用
1.下面以一個實例來說明其使用,先看properties格式配置
application.properties
server.port=8000
jdbc_url=jdbc:mysql://127.0.0.1:3306/test
student.id=1003
student.name=tom
student.age=30
student.desc=${student.name} is a student, ${student.age} years old this year
StudentConfig 配置
@ConfigurationProperties注入配置屬性前綴,prefix指定前綴。
@Component
@ConfigurationProperties(prefix="student")
public class StudentConfig {
private String id;
private String name;
private int age;
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;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
ConfigController:
@Value注入配置文件屬性值,冒號分割“:”,不存在取默認。
@RestController
public class ConfigController {
@Value("${jdbc_url:jdbc:mysql://localhost:3306/test}")
private String jdbcUrl;
@Value("${student.desc}")
private String desc;
@Autowired
private StudentConfig studentConfig;
@RequestMapping(value="/jdbc",method = RequestMethod.GET)
public String jdbc(){
return jdbcUrl;
}
@RequestMapping(value="/student",method = RequestMethod.GET)
public String studentConfig(){
return studentConfig.toString();
}
@RequestMapping(value="/desc",method = RequestMethod.GET)
public String desc(){
return desc;
}
}
2.啓動服務,請求對於的url,可以查看返回的參數
下面用yaml編寫配置文件看看,application.yml
server:
port: 8000
jdbc_url: jdbc:mysql://127.0.0.1:3306/test
student:
id: 1003
name: tom
age: 30
desc: ${student.name} is a student, ${student.age} years old this year
層次感很強,配置也比properties清晰很多。注意下級比上級縮進2個空格,屬性與屬性值冒號加空格分割
2.使用Profile區分環境
spring boot中,可以通過在application.yml配置文件中,配置多個不同的profile,實現在不同的環境(比如開發、測試和生產環境)使用不同的配置變量。
如下:
server:
port: 8000
student:
id: 1003
name: tom
age: 30
desc: ${student.name} is a student, ${student.age} years old this year
# 默認的profile爲dev,其他環境通過指定啓動參數使用不同的profile
spring:
profiles:
active: dev
---
# 開發環境配置
spring:
profiles: dev
jdbc_url: jdbc:mysql://127.0.0.1:3306/test
---
# 測試環境配置
spring:
profiles: test
jdbc_url: jdbc:mysql://192.168.1.20:3306/test
各個環境配置使用”—”分割,默認啓動時dev,如使用其他環境,啓動參數增加 :spring.profiles.active=test
如:java -jar my-spring-boot.jar –spring.profiles.active=test
也可以將如上拆分成多個不同環境文件,這個配置更清晰,如:通過文件名來區分環境 application-{profile}.yml
將公共的都放在application.yml裏面,因環境變化的都放在application-{profile}.yml文件裏
application.yml
server:
port: 8000
student:
id: 1003
name: tom
age: 30
desc: ${student.name} is a student, ${student.age} years old this year
# 默認的profile爲dev,其他環境通過指定啓動參數使用不同的profile
spring:
profiles:
active: dev
application-dev.yml
jdbc_url: jdbc:mysql://127.0.0.1:3306/test
application-test.yml
jdbc_url: jdbc:mysql://192.168.1.20:3306/test
在啓動程序的時候通過添加 –spring.profiles.active={profile} 來指定具體使用的配置。Spring Boot 會先加載默認的配置文件,然後使用具體指定的profile中的配置去覆蓋默認配置。
注:
1.Java類中可以使用@Profile註解指定了具體環境,不建議這樣使用。如:
// 接口定義
public interface SendMessage {
// 發送短信方法定義
public void send();
}
// Dev 環境實現類
@Component
@Profile("dev")
public class DevSendMessage implements SendMessage {
@Override
public void send() {
System.out.println(">>>>>>>>Dev Send()<<<<<<<<");
}
}
// Stg環境實現類
@Component
@Profile("stg")
public class StgSendMessage implements SendMessage {
@Override
public void send() {
System.out.println(">>>>>>>>Stg Send()<<<<<<<<");
}
}
// 啓動類
@SpringBootApplication
public class ProfiledemoApplication {
@Value("${app.name}")
private String name;
@Autowired
private SendMessage sendMessage;
@PostConstruct
public void init(){
sendMessage.send();// 會根據profile指定的環境實例化對應的類
}
}
2.logback-spring.xml也支持有節點來支持區分,文件名不要用logback.xml 請使用logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml" />
<logger name="org.springframework.web" level="INFO"/>
<springProfile name="default">
<logger name="org.springboot.sample" level="TRACE" />
</springProfile>
<springProfile name="dev">
<logger name="org.springboot.sample" level="DEBUG" />
</springProfile>
<springProfile name="staging">
<logger name="org.springboot.sample" level="INFO" />
</springProfile>
</configuration>
3.指定外部的配置文件
java -jar demo.jar --spring.config.location=/ect/demo/application.properties
3.獲取環境變量
凡是被spring管理的類,實現接口 EnvironmentAware 重寫方法 setEnvironment 可以在工程啓動時,獲取到系統環境變量和application配置文件中的變量。
@Configuration
public class AppConfigurer implements EnvironmentAware
{
private static final Logger logger = LoggerFactory.getLogger(AppConfigurer.class);
private RelaxedPropertyResolver propertyResolver;
@Value("${jdbc_url}")
private String jdbcUrl;
@Override
public void setEnvironment(Environment env) {
logger.info(env.getProperty("JAVA_HOME"));
logger.info(jdbcUrl);
String str = env.getProperty("student.name");
logger.info(str);
propertyResolver = new RelaxedPropertyResolver(env, "student.");
String desc= propertyResolver.getProperty("desc");
logger.info(desc);
}
}
@Controller @Service 等被Spring管理的類都支持,注意重寫的方法 setEnvironment 是在系統啓動的時候被執行。
關於配置讀取的幾個註解:
實例
@Configuration
@ConditionalOnClass(Redis.class)
@EnableConfigurationProperties(RedisProperties.class)
@ConditionOnClass 表明該@Configuration僅僅在一定條件下才會被加載,這裏的條件是Redis.class位於類路徑上
@EnableConfigurationProperties 將Spring Boot的配置文件(application.properties)中的spring.data.redis.*屬性映射爲RedisProperties並注入到RedisAutoConfiguration中。
@ConditionalOnMissingBean 說明Spring Boot僅僅在當前上下文中不存在Redis對象時,纔會實例化一個Bean。這個邏輯也體現了Spring Boot的另外一個特性——自定義的Bean優先於框架的默認配置,我們如果顯式的在業務代碼中定義了一個Redis對象,那麼Spring Boot就不再創建。
實例源碼:https://github.com/slimina/springboot-study