Skip to main content

配置

YAML配置文件#

框架主配置文件由bootstrap和application两个组成,以.yml或.yaml扩展名结尾。通常情况下bootstrap主要是一些底层核心配置项目,以及运行环境设定。 application则负责一些上层应用层配置项。如果默认配置适用,可以只启用任意一个配置文件甚至不启用任何一个配置文件。由于本框架支持多应用,所以除了 这两个全局配置文件外,如果需要,每个应用还可以有自己的特定的配置文件,该配置文件名和该应用的启动类文件名相同。bootstrap中的设置项会被application 和应用配置文件继承,如果application中存在和bootstrap中相同的配置项,那么会以bootstrap中的为准,即bootstrap的配置项会被继承但不会被覆盖。每个配置 还可以按环境拆分为主配置和环境子配置文件,此时配置文件的子配置文件会覆盖主配置中相同的配置项。 下面是一个最简单的配置,设定WEB服务的IP和端口号:

# bootstrap configuration
---
readyWork:
server:
# This is the default binding address.
ip: 0.0.0.0
# Http port if enableHttp is true.
httpPort: 8080

和Spring一样,这些配置文件均支持环境分离配置,如果我们需要按环境分离配置文件,可以这样操作:

  1. 定义一个总的bootstrap.yml配置文件
bootstrap.yml
# configuration
---
readyWork:
profiles:
active: dev

如果总配置文件中也包含有配置项,且该配置项也出现在环境子配置文件中,则最终的值为环境子配置项目的值,即会被环境子配置文件中相同配置项覆盖。

  1. 然后再定义几个子bootstrap配置文件,即配置文件名增加环境后缀,如bootstrap-dev.yml,bootstrap-test.yml,bootstrap-prod.yml等,每个配置文件可以指定不同的IP和端口号:
bootstrap-dev.yml
# configuration for dev environment
---
readyWork:
server:
# This is the default binding address.
ip: 0.0.0.0
# dynamic port is used for containerization
dynamicPort: false
# Http port if enableHttp is true.
httpPort: 8080
bootstrap-test.yml
# configuration for test environment
---
readyWork:
server:
# This is the default binding address.
ip: 192.168.1.10
# Http port if enableHttp is true.
httpPort: 8081
  1. 通过修改总的bootstrap.yml配置文件的active的值为dev或test就可以切换环境。和Spring一样,也可以通过环境变量来切换环境,而无需每次修改总配置文件。 例如通过启动应用时加上JVM参数-DreadyWork.profiles.active=test,即可动态切换配置为test环境。

通过环境变量设置#

上述配置文件中的配置项均可通过外部环境变量来设置,配置项目的覆盖优先级如下:

命令行参数 > JVM参数 > 系统环境变量 > yaml配置文件

命令行参数和JVM参数类似,都是在启动应用时候的命令行中,参数名就是配置项路径,例如:

  • readyWork.profiles.active=test
  • readyWork.server.ip=192.168.1.1

系统环境变量稍有不同,需要将配置项路径中的点替换为下划线,例如:

  • readyWork_profiles_active=test
  • readyWork_server_ip=192.168.1.1

通过程序配置#

在主应用启动类中添加一个protected void globalConfig(ApplicationConfig config)方法,即可对bootstrap config进行操作。基本上Boostrap中的配置项都可以通过globalConfig进行程序化配置。例如:

public class Main extends Application {
@Override
protected void globalConfig(ApplicationConfig config) {
config.getDatabase().setDataSource("test", new DataSourceConfig()
.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&useSSL=false&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull")
.setUsername("root").setPassword("12345678")
);
}
public static void main(String[] args) {
Ready.For(Main.class).Work(args);
//支持多个Application
//Ready.For(Main.class, AnotherApp.class).Work(args);
}
}

通过这里进行程序化设置会覆盖从配置文件或环境变量中读取的配置项。当有多个应用时,启动类中的第一个应用为主应用,只有主应用可以进行globalConfig配置设定。

在每个应用中都可以通过添加一个protected void appConfig(ApplicationConfig config)方法,可以对应用层的application config进行操作。但这些配置继承自Boostrap,并附加读取了application和当前应用的配置文件。修改只对当前应用层组件的配置项有效。

public class Main extends Application {
@Override
protected void appConfig(ApplicationConfig config) {
// 这里可以对应用层的config进行设定,这里的值继承自Boostrap,并附加读取了application和当前应用的配置文件。
}
public static void main(String[] args) {
Ready.For(Main.class).Work(args);
//支持多个Application
//Ready.For(Main.class, AnotherApp.class).Work(args);
}
}

通过这里进行程序化设置会覆盖从配置文件或环境变量中读取的配置项。当有多个应用时,各个应用可以对各自的application config进行配置设定,修改只对应用层组件和各应用特有组件产生作用。

动态可变配置项#

配置项的值可以是变量的形式设置,随后由系统将变量更新为正式值。例如:

bootstrap-dev.yml
# configuration for dev environment
---
readyWork:
server:
# This is the default binding address.
ip: ${httpIp}
# dynamic port is used for containerization
dynamicPort: false
# Http port if enableHttp is true.
httpPort: ${httpPort}

然后在values.yml中对该变量进行设置,以后可以通过更新values.yml来集中维护各配置文件中的可变配置项。

values.yml
---
httpIp: 192.168.1.100
httpPort: 8089

动态配置注入#

配置项可以通过对象访问,也可以通过@Value注解注入到类的属性中,例如:

@RequestMapping(value = "/")
public class DemoController extends Controller {
//this is to get value from values.yaml, if it's not exist the default 127.0.0.1 will be used
@Value("${httpIp:127.0.0.1}")
String serverIp;
//this is to get value from values.yaml, if it's not exist the default 8080 will be used
@Value("${httpPort:8080}")
String serverPort;
//this is to get value from bootstrap/application config
@Value(value = "${readyWork.server.dynamicPort}", source = Value.Source.APPLICATION)
boolean dynamicPort;
@RequestMapping
public Result<String> index() {
return Success.of(
"serverIp: " + serverIp + "," +
"serverPort: " + serverPort + "," +
"dynamicPort: " + dynamicPort);
}
}

注意,目前@Value注解注入配置项只读取配置加载后的值,如果通过程序修改了bootstrap/application配置,@Value注入的值依然是配置文件加载时的值。

自定义配置Bean绑定#

如果自定义来配置项,同时自定义了配置Class,那么可以将它们进行自动绑定。

  1. 我们在上面的实例配置文件中添加一组和readyWork同层级的顶级配置项otherConfig
bootstrap-dev.yml
# configuration for dev environment
---
readyWork:
server:
# This is the default binding address.
ip: ${httpIp}
# dynamic port is used for containerization
dynamicPort: false
# Http port if enableHttp is true.
httpPort: ${httpPort}
otherConfig:
key1: value1
key2: value2
  1. 我们定一个配置Class并进行绑定
@ConfigurationProperties(prefix = "${otherConfig}")
public class OtherConfig extends BaseConfig {
String key1;
String key2;
public String getKey1() {
return key1;
}
public void setKey1(String key1) {
this.key1 = key1;
}
public String getKey2() {
return key2;
}
public void setKey2(String key2) {
this.key2 = key2;
}
}
  1. 我们注入这个Bean来使用
@RequestMapping(value = "/")
public class DemoController extends Controller {
//this is to get value from values.yaml, if it's not exist the default 127.0.0.1 will be used
@Value("${httpIp:127.0.0.1}")
String serverIp;
//this is to get value from values.yaml, if it's not exist the default 8080 will be used
@Value("${httpPort:8080}")
String serverPort;
//this is to get value from bootstrap/application config
@Value(value = "${readyWork.server.dynamicPort}", source = Value.Source.APPLICATION)
boolean dynamicPort;
@Autowired
OtherConfig otherConfig;
@RequestMapping
public Result<String> index() {
return Success.of(
"serverIp: " + serverIp + "," +
"serverPort: " + serverPort + "," +
"dynamicPort: " + dynamicPort);
}
@RequestMapping
public Result<OtherConfig> autoConfig() {
return Success.of(otherConfig);
}
}
  1. 如果otherConfig配置项放在一个单独的fileName.yaml文件中,而不是添加在bootstrap/application配置文件中,可以这样修改注解即可
  • @ConfigurationProperties(prefix = "${otherConfig}", file = "fileName")

直接读取自定义配置文件#

如果需要自定义自己的配置文件或配置项,可以通过以下方法实现:

  1. 读取自定义配置文件,即读取自己的yaml配置文件
  • BeanType config = Ready.config().getObjectConfig(configFile, BeanType.class);

configFile为yaml配置文件名,BeanType是自定义的配置Class,如果不定义自己的Class也可以直接用Map代替。

  • Map config = Ready.config().getObjectConfig(configFile, Map.class);
  1. 从bootstrap/application中读取自定义配置项 用下面方法即可读取上例中bootstrap的otherConfig配置项
  • Map config = ConfigInjector.getConfigBean("${otherConfig}", Map.class, null, null);

这里用Map作为容器,如果需要可以定义自己的配置Class来替换Map。

配置项加密#

有些时候我们需要对部分配置项目进行加密保护,例如数据库连接密码、API密钥等,避免明文显示在配置文件中。

  1. 运行work.ready.core.component.decrypt.AESEncryptor,参数为你需要加密的文本或密码,输出为以CRYPT:为前缀的加密内容。
  2. 将yaml配置文件中明文的密码或待加密文本替换为第1步中获得的加密内容。
  3. 通过前面介绍的各种方式读取配置项,即可自动解密,得到的会是已经解密的内容。 这种方式的加密只能保护不被外部人员获得加密内容,如果需要对内部技术团队也保持加密保护,后续将有专题讲解。