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

猜你喜欢

转载自blog.csdn.net/tianwei7518/article/details/69935962