Spring Boot探路者之應用配置

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章