Spring Boot学习笔记-外部化属性配置

看过前几篇系列文章的人,应该会对“application.properties”字眼比较熟悉。其实这就牵引出了Spring Boot外部化属性配置的内容。

properties文件在Java中一直充当着属性配置的角色,我们可以将应用中涉及配置方面的键值对内容放入properties文件中,方便我们在一个地方集中地管理配置项。

Spring Boot总会帮我们考虑的实践中可能常用的技巧,所以在Spring Boot应用中使用属性配置会更加轻松上手。Spring Boot外部化属性配置主要有两方面的体现:

  1. 针对Spring Boot特性及自动配置的控制。比如之前我们提到的数据源的配置、日志文件的配置等等。
  2. 自定义属性的配置及引用。

属性加载原则

Spring Boot应用中,属性的来源可能很多,针对不同来源的属性,会有优先级顺序。同名情况下,优先级高的会覆盖优先级低的。如下:

输入图片说明

不同次序的载入,可以扩展使用的灵活度。比如针对一次性的测试,你可以用命令行的方式追加属性配置,而无需再去修改配置文件。

Spring Boot的默认配置

看到上面的加载原则,又见到了“application.properties”的身影。没错,以往我们的属性配置文件都是自定义并指定载入的。Spring Boot默认为我们提供了一个配置之地!只要按照指定的名称创建属性文件,并放置在指定位置,Spring Boot会自动解析其内容。

默认情况下Spring Boot会从以下位置寻找application.properties文件,并把属性加入到Spring Environment中。

  1. 当前目录下的一个/config子目录
  2. 当前目录
  3. 一个classpath下的/config包
  4. classpath根路径(root)

上述列表中的位置优先级自上而下递减,同样的属性配置,高位置的会覆盖低位置的!

假如你不喜欢“application.properties”这个默认文件名,你可以重新设定:

  • spring.config.name属性直接指定属性文件名称。
  • spring.config.location属性指定明确路径。

**ps:**例如spring.config.location=classpath:mine.properties,classpath:config/mine.properties,多个文件路径以逗号间隔。如果路径以最后为目录,必须以"/"结尾。例如spring.config.location=classpath:myconfig/,那么spring.config.name会自动追加到后面!一旦设定了spring.config.location属性,上述的默认位置将不起作用!

因为你要修改的是application.properties的名称,所以上面的两个属性建议通过命令行的方式配置,如:java -jar xxx.jar --spring.config.name=mine.properties。当然你还可以通过环境变量等方式,请参考上面的默认加载原则。

同理,上述的默认配置规则适用于YAML方式(后面会详述)。表面区别只在于,将“.properties”改为“.yml”即可。

命令行属性

默认情况下,Spring Boot应用会将命令行任何可选的参数(以“--”开头,如--server.port=90)转化为property并添加到Spring environment中。

如果你想禁止这一行为,可使用代码:SpringApplication.setAddCommandLineProperties(false)

属性的配置方式

Spring Boot提供了两种属性配置方式,一种是传统的properties文件,一种是YAML。后者笔者也是略知一二,并无实践经验。

properties方式

这种方式自然需要properties文件,适合于键值对形式的属性配置。

properties文件中可以使用占位符,引用之前定义的其他属性值!例如:

app.name=MyApp
app.description=${app.name} is a Spring Boot application

YAML方式

YAML是Json的一个超集,更适合于具有层次结构形式的属性配置。你只要将SnakeYAML库放在classpath下,SpringApplication类会自动将YAML转化为properties属性。如果你使用了“Starter POMs”,会自动提供SnakeYAML。YAML学习入口

YAML文档以“.yml”结尾,格式如下:

environments:
	dev:
		url: http://dev.bar.com
		name: Developer Setup
	prod:
		url: http://foo.bar.com
		name: My Cool App

上面的文档结构会被转化为:

environments.dev.url=http://dev.bar.com
environments.dev.name=Developer Setup
environments.prod.url=http://foo.bar.com
environments.prod.name=My Cool App
YAML列表

YAML还有一种列表格式,如下:

my:
	servers:
		- dev.bar.com
		- foo.bar.com

转化之后呢,变为:

my.servers[0]=dev.bar.com
my.servers[1]=foo.bar.com

无论是properties方式还是YAML方式,都可以通过传统的@Value("${property}")注解的方式引用属性值。

属性配置beans

有时你会觉着@Value("${property}")注解引用属性值会很笨重,特别是需要使用多个properties或者使用的属性具有层次结构。

Spring Boot允许你将属性值绑定到强类型的beans上面。需要两个条件:

  1. 定义属性bean,使用@ConfigurationProperties注解,bean的属性名称与properties匹配,并提供对应的setter方法。
  2. @Configuration类上需要使用@EnableConfigurationProperties注解,那么任何被@ConfigurationProperties注解的beans将自动被Environment属性配置。

下面是一段代码示例:

@Component
@ConfigurationProperties(prefix="connection")
	public class ConnectionSettings {
	private String username;
	private InetAddress remoteAddress;
	// ... getters and setters
}

其实这种风格特别适合于YAML方式配合使用。下面是对应的yml文档内容:

# application.yml
connection:
	username: admin
	remoteAddress: 192.168.1.1

针对YAML列表格式的属性,绑定到bean上有几点需要注意:

  1. bean中必须有个java.util.List或Set类型的属性。
  2. 除了setter方法初始化属性外,还可以可变的值初始化属性。(笔者认为setter更直观常用)

下面是列表格式的示例:

@ConfigurationProperties(prefix="my")
	public class Config {
		private List<String> servers = new ArrayList<String>();
		public List<String> getServers() {
		return this.servers;
	}
}

你可以使用注入的方式来使用属性bean,如下:

@Service
public class MyService {
	@Autowired
	private ConnectionSettings connection;
	//...
	}
}

同样地,属性还可以绑定到第三方的组件bean上,只要符合上面提到的两个条件,@ConfigurationProperties应用到@Configuration类中的@Bean上即可。如下:

@ConfigurationProperties(prefix = "foo")
@Bean
public FooComponent fooComponent() {
...
}

属性bean的方式还有一个优势,你可以@ConfigurationProperties类添加JSR-303 javax.validation约束注解,例如:

@Component
@ConfigurationProperties(prefix="connection")
	public class ConnectionSettings {
	@NotNull
	private InetAddress remoteAddress;
	// ... getters and setters
}
松散的绑定

上面提到属性绑定bean时,bean的属性名称应该与properties匹配。其实这方面Spring Boot提供了一种松散的机制,不需要精确匹配。像操作系统的环境变量不允许使用句号却可以使用下划线分隔,Spring Boot提供了很好的转化。规则如下:

  1. 标准驼峰格式:person.firstName
  2. 虚线格式(推荐.properties和.yml文件中):person.first-name
  3. 大写形式(推荐系统环境变量使用):PERSON_FIRST_NAME

上面的三种格式,都会绑定到下面bean中的firstName属性上。

@Component
@ConfigurationProperties(prefix="person")
public class ConnectionSettings {
	private String firstName;
}

转载于:https://my.oschina.net/angerbaby/blog/596360

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值