博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring核心——资源数据管理
阅读量:5888 次
发布时间:2019-06-19

本文共 4981 字,大约阅读时间需要 16 分钟。

  hot3.png

在一文中介绍了环境的概念以及Spring Profile特性控制Bean的添加。本文将进一步介绍Spring管理和控制操作系统变量、JVM变量和Java标准资源(properties文件)的相关功能。

文章的代码仅仅用于说明问题,,本文的代码在chkui.springcore.example.hybrid.propertsource包中。

PropertySource与优先级

在整个Jvm运行期间,我们可以随时随地获取到2个与环境相关的参数:

package chkui.springcore.example.hybrid.propertsource;//env是与操作系统相关的参数Map
env = System.getenv();//properties中是Jvm相关的参数Properties p = System.getProperties();System.out.println("env :" + env);System.out.println("properties :" + p);

如果没有人为的添加额外信息,System::getEnv获取的数据都与当前的操作系统相关(以下称为“操作系统参数”),而System::getProperties获取的内容都与Jvm相关(以下称为“JVM参数”)。

Spring会将操作系统参数和Jvm参数都整合到自己的环境管理接口Environment中,例如下面的代码:

package chkui.springcore.example.hybrid.propertsource;//向系统级的properties设置一个参数System.setProperty("wow", "World of Warcraft");ApplicationContext ctx = new AnnotationConfigApplicationContext(PropertySourcesApp.class);//通过spring的Environment获取参数Environment springEnv = ctx.getEnvironment();System.out.println(springEnv.getProperty("wow"));System.out.println(springEnv.getProperty("PATH"));

除了我们自定义的"wow",操作系统参数"PATH"也可以在Spring的Environment中获取。

通常情况下,在Environment内部维护了2个的实例:一个是操作系统参数,另外一个是JVM参数。如果2者有同样的参数,那么我们在调用Environment::getProperty方法时,得到的是JVM参数(System::getProperties),也就是说 Jvm参数具有更高的优先级。

除了通过外部设置,我们也可以直接使用Spring提供的接口来设置:

package chkui.springcore.example.hybrid.propertsource;//我们要对环境进行配置,需要使用ConfigurableApplicationContext接口ConfigurableApplicationContext configAbleCtx = new AnnotationConfigApplicationContext(PropertySourcesApp.class);//ConfigurableApplicationContext接口提供对应的可编辑Environment和PropertySourcesMutablePropertySources ps = configAbleCtx.getEnvironment().getPropertySources();Map
map = new HashMap
();map.put("wow", "Origin = World of Warcraft!But Edit it already!");//添加到Spring的环境参数中ps.addFirst(new MapPropertySource("myPropertySource", map));System.out.println(springEnv.getProperty("wow"));

代码添加到PropertySource中,Environment会额外维护一个,而自己添加的优先级是最高的,所以最后Environment::getProperty获取到的值是最后设置的值。

如果需要添加多个,可以通过MutablePropertySources::addFirstMutablePropertySources::addLast方法来控制他们之间的优先级。

引入资源文件

*.properties是Java的标准资源文件,在Java的各种项目中常用来记录各种配置参数。Spring提供了注解和XML配置将*.properties文件中的数据整合到Spring的环境参数(Environment)中。

@PropertySource

@Configuration标记的类上使用@PropertySource注解可以引入0~n个*.properties配置文件。如下面的例子:

package chkui.springcore.example.hybrid.propertsource;@Configuration@PropertySource("classpath:/hybrid/propertysource/config.properties")public class PropertySourcesApp {	public static void main(String[] args) {		ApplicationContext ctx = new AnnotationConfigApplicationContext(PropertySourcesApp.class); 		System.out.println("Properties file params: " + springEnv.getProperty("Gdi"));	}}

对应的config.properties文件:

#hybrid.propertysource.config.propertiesGdi=StarCraft

同一个工程中支持使用多个@PropertySource注解来引入配置文件,也支持Ant风格(Ant-style,例如"classpath:a/b/**/config.properties")以及Spring扩展的(比如"classpath*:")的路径规则,资源路径控制会在后续的文章中介绍。

XML配置

XML配置在之前介绍容器后置处理器——的文章中已经介绍了,他就是 PropertyPlaceholderConfigurer ,我们在XML配置文件中进行一下设置即可。

引入Bean:

直接使用context进行全局设置:

占位符替换

PropertyPlaceholderConfigurer继承了抽象类PropertyPlaceholderConfigurer,*.properties文件的读写就是在PropertyResourceConfigurer类中实现的。PropertyPlaceholderConfigurer进一步实现了配置文件中占位符(${...})替换功能

在Spring IoC容器执行Bean的扫描、加载之前添加一个环境变量(也可以动态添加然后再执行ConfigurableApplicationContext::refresh方法),就可以在很多资源路径的位置使用这个占位符,对上面的例子进行一些修改:

@Configuration//通过占位符来设置路径@PropertySource("classpath:${resource.propertiesPath}/config.properties")public class PropertySourcesApp {	public static void main(String[] args) {        //容器启动之前设置环境变量		System.setProperty("resource.propertiesPath", "/hybrid/propertysource");		ApplicationContext ctx = new AnnotationConfigApplicationContext(PropertySourcesApp.class);		//获取环境对象实例		Environment springEnv = ctx.getEnvironment();		System.out.println("Properties : " + springEnv.getProperty("Gdi"));	}}

同样的,只要环境变量存在,也可以使用占位符替换配置文件中的数据,例如:

XML中的占位符使用的格式是${resource.propertiesPath:/config},它表示使用环境变量resource.propertiesPath进行替换,如果resource.propertiesPath不存在则使用值"/config"。

我们可以在任何Bean中使用@Value注解来获取环境变量。如下面的例子:

package chkui.springcore.example.hybrid.propertsource;@Configurationpublic class PropertySourcesApp {	@Value("${resource.propertiesPath}")	private String value;	@Value("#{systemProperties['resource.propertiesPath']}")	private String elValue;	@Value("Resource PropertiesPath")	private String staticValue;		public static void main(String[] args) {		System.setProperty("resource.propertiesPath", "/hybrid/propertysource");		ApplicationContext ctx = new AnnotationConfigApplicationContext(PropertySourcesApp.class);				PropertySourcesApp app = ctx.getBean(PropertySourcesApp.class);		System.out.println("Value: " + app.value);		System.out.println("EL Value: " + app.elValue);		System.out.println("Static Value: " + app.staticValue);	}}

@Value可以注入一个纯字面量,如上面示例代码中的staticValue,也可以使用占位符使用环境变量中的任何值。除了使用占位符${},@Value还支持"#{systemProperties['resource.propertiesPath']}"这样具备代码执行功能的复杂表达式来获取数据,这部分功能会在后续介绍EL表达式的文章中进行分享。

转载于:https://my.oschina.net/chkui/blog/1920637

你可能感兴趣的文章
Linux下的搜索查找命令的详解(locate)
查看>>
安装gulp及相关插件
查看>>
如何在Linux用chmod来修改所有子目录中的文件属性?
查看>>
高并发环境下,Redisson实现redis分布式锁
查看>>
Hyper-V 2016 系列教程30 机房温度远程监控方案
查看>>
笔记:认识.NET平台
查看>>
cocos2d中CCAnimation的使用(cocos2d 1.0以上版本)
查看>>
【吉光片羽】短信验证
查看>>
gitlab 完整部署实例
查看>>
GNS关于IPS&ASA&PIX&Junos的配置
查看>>
影响企业信息化成败的几点因素
查看>>
SCCM 2016 配置管理系列(Part8)
查看>>
struts中的xwork源码下载地址
查看>>
ABP理论学习之仓储
查看>>
我的友情链接
查看>>
CentOS图形界面和命令行切换
查看>>
HTML5通信机制与html5地理信息定位(gps)
查看>>
加快ALTER TABLE 操作速度
查看>>
PHP 程序员的技术成长规划
查看>>
python基础教程_学习笔记19:标准库:一些最爱——集合、堆和双端队列
查看>>