转载

每日一博 | Spring 核心——资源数据管理

随风溜达的向日葵 spring

正文

每日一博 | Spring 核心——资源数据管理

Spring核心——资源数据管理

每日一博 | Spring 核心——资源数据管理
  随风溜达的向日葵 发布于 08/01 10:26

字数 1406

阅读 889

收藏 8

点赞 2

评论 0

Spring

十年阿里,就只剩下这套Java开发体系了 >>> 每日一博 | Spring 核心——资源数据管理

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

文章的代码仅仅用于说明问题, 可执行代码请到我的gitee库clone ,本文的代码在 chkui.springcore.example.hybrid.propertsource 包中。

PropertySource与优先级

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

package chkui.springcore.example.hybrid.propertsource;

//env是与操作系统相关的参数
Map<String, String> 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个 PropertySources 的实例:一个是操作系统参数,另外一个是JVM参数。如果2者有同样的参数,那么我们在调用 Environment::getProperty 方法时,得到的是JVM参数( System::getProperties ),也就是说 Jvm参数具有更高的优先级。

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

package chkui.springcore.example.hybrid.propertsource;

//我们要对环境进行配置,需要使用ConfigurableApplicationContext接口
ConfigurableApplicationContext configAbleCtx = new AnnotationConfigApplicationContext(PropertySourcesApp.class);

//ConfigurableApplicationContext接口提供对应的可编辑Environment和PropertySources
MutablePropertySources ps = configAbleCtx.getEnvironment().getPropertySources();
Map<String, Object> map = new HashMap<String, Object>();
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会额外维护一个 PropertySources ,而自己添加的 PropertySources 优先级是最高的,所以最后Environment::getProperty获取到的值是最后设置的值。

如果需要添加多个 PropertySources ,可以通过 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.properties

Gdi=StarCraft

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

XML配置

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

引入Bean:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <!-- 指定*.properties文件的路径 -->
    <property name="locations" value="classpath:/hybrid/propertysource/config.properties"/>
</bean>

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

<context:property-placeholder location="classpath:/hybrid/propertysource/config.properties"/>

占位符替换

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"));
	}
}

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

<context:property-placeholder location="classpath:${resource.propertiesPath:/config}/config.properties"/>

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

@Value

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

package chkui.springcore.example.hybrid.propertsource;

@Configuration
public 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表达式的文章中进行分享。

© 著作权归作者所有

共有人打赏支持

每日一博 | Spring 核心——资源数据管理

随风溜达的向日葵

粉丝 239

博文 68

码字总数 147842

作品 0

广州

其他

相关文章 最新文章

Spring核心——FactoryBean

本文继续之前的2篇文章(BeanPostProcessor和BeanFactoryPostProcessor)介绍Ioc容器的功能扩展。 FactoryBean是用来构造Bean的接口。常规情况下向容器添加一个Bean只需要像下面这样通过XML...

随风溜达的向日葵

07/12

0

0

Spring(一)——总体介绍

工作闲着,快速回顾一下spring框架。Spring框架,是进行对象管理,对象关联,解耦的一个中间层框架。SSH(Struts+Spring+Hibernate)三大Spring在中间就起着一个承上启下的作用。好,首先我们...

凡尘里的一根葱

2015/11/10

0

0

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密...

小致dad

08/03

0

0

Spring核心——JSR250与资源控制

JSR-175与元编程 要说明JSR-250先要解释清楚JSR-175,要解释清楚JSR就的先了解JCP是什么。网上资料很多,就不细说了,简单的说JCP(Java Community Process)是管理Java生态(包括J2SE、J2E...

随风溜达的向日葵

07/18

0

0

Spring核心——纯Java运行与@Bean

3.0新增容器启动方法 在3.0之前的Spring核心框架中,我们启动一个Spring容器必须使用一个XML文件。而到了3.X之后的版本Spring为创建容器新增了一个入口类——AnnotationConfigApplicationCo...

随风溜达的向日葵

07/24

0

0

springMVC笔记系列(18)——配置文件细节详解

本文着重说说springMVC项目中各个配置文件的一些细节。 web.xml文件是web应用的部署描述。 在上一节的springMVC示例中 ,idea下的Maven-webapp项目自动生成了web.xml文件,用的是webapp2.3的...

HappyBKs

2016/06/14

1K

0

SpringMVC深度探险(三) —— DispatcherServlet与初始化主线 博客分类:

SpringMVC深度探险(三) —— DispatcherServlet与初始化主线 博客分类: SpringMVC 本文是专栏文章(SpringMVC深度探险)系列的文章之一,博客地址为:http://downpour.iteye.com/blog/13...

xiguashare

2013/12/09

0

0

Spring核心——上下文与IoC

前面3篇分别介绍了IoC容器与Bean的关系、Bean与Bean之间的关系以及Bean自身的控制和管理。在了解Spinrg核心模式时,一定要谨记他的基本工作元素就是IoC容器和Bean,所有的功能是围绕着这2者展...

随风溜达的向日葵

07/02

0

0

Spring实战读书笔记(1)

Spring的根本使命是? 简化Java开发 为了降低Java开发的复杂性,Spring采取了哪4种关键策略? 1、基于POJO的轻量级和最小侵入性编程 2、通过依赖注入和面向接口实现松耦合 3、基于切面和惯例...

祥林会跟你远走高飞

2014/12/30

0

0

Spring_总结_02_依赖注入

一、前言 本文承接上一节:Spring总结01_Spring概述 在上一节中,我们了解了Spring的最根本使命、四大原则、六大模块以及Spring的生态。 这一节我们开始了解Spring的第二大原则中的依赖注入,...

rayner

07/27

0

0

每日一博 | Spring 核心——资源数据管理

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Mybatis-Plus使用全解

前言 之前写了《SpringBoot | 第九章:Mybatis-plus的集成和使用》一文,只是简单的使用条件构造器列举了一些通用的CURD操作。本人也想写一篇通用的关于mybatis-plus的使用示例,一方面也让自...

oKong

17分钟前

1

0

每日一博 | Spring 核心——资源数据管理
Netty(三) 什么是 TCP 拆、粘包?如何解决?

前言 记得前段时间我们生产上的一个网关出现了故障。 这个网关逻辑非常简单,就是接收客户端的请求然后解析报文最后发送短信。 但这个请求并不是常见的 HTTP ,而是利用 Netty 自定义的协议。...

crossoverJie

21分钟前

0

0

每日一博 | Spring 核心——资源数据管理
什么是7层负载均衡?

在开源PaaS Rainbond中,我们对各种应用层协议匹配不同的网络治理插件,以实现7层负载均衡(layer 7 load balancing),例如HTTP、gRPC、Redis等协议。原因在于对于一些在线环境,我们希望可...

好雨云帮

23分钟前

0

0

第六章——容器扩展点

通常,应用开发人员不需要实现ApplicationContext子类。而是,通过扩展Spring IoC容器的集成接口。 1 使用BeanPostProcessor自定义Bean 你可以实现BeanPostProcessor接口定义回调方法,提供自...

Leech

今天

1

0

OSChina 周一乱弹 —— 妮儿还是把上衣穿上吧

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @Sharon啊:分享二珂的单曲《藏着》 《藏着》- 二珂 手机党少年们想听歌,请使劲儿戳(这里) 这样的一个夏天, 每到假期, 总过不好, 无论安...

小小编辑

今天

177

13

每日一博 | Spring 核心——资源数据管理
微服务资源springboot、springcloud、docker、dubbo项目实战等倾心分享

精彩内容 java实战练习项目教程 全网最全电子图书分享 你所需要的大数据视频教程 java学习视频教程及源码 今天又是周末,还是想给大家送一些福利,因为最近一直有小伙伴问我要springboot等微...

公众号_好好学java

今天

1

0

一只菜鸡的半年技术博客之路

我写作的初心 做 IT或者程序员工作的我们都知道(其实不只限于IT,我想其他行业也是如此),平时的学习工作过程中,难免会遇到各种问题需要查资料的情形,此时就某一技术问题我们在因特网上会...

CodeSheep

今天

1

0

每日一博 | Spring 核心——资源数据管理
jQuery零基础入门——(八)AJAX

《jQuery零基础入门》系列博文是在廖雪峰老师的博文基础上,可能补充了个人的理解和日常遇到的点,用我的理解表述出来,主干出处来自廖雪峰老师的技术分享。 用JavaScript写AJAX前面已经介绍...

JandenMa

今天

1

0

搭建git服务器#180806

服务器 [root@localhost ~]# yum install -y git[root@localhost ~]# useradd -s /usr/bin/git-shell git[root@localhost ~]# cd /home/git/[root@localhost git]# ls[root@localhost g......

hellopasswd

今天

0

0

Confluence 6 配置 Web 代理支持

这个页面中的相关平台中的内容是不被支持的。因此,Atlassian 支持不能保证能够为你提供任何支持。请注意,这个页面下面提供的信息仅为你提供参考同时也不能保证所有的的配置能正常工作。如果...

honeymose

今天

0

0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

原文  https://my.oschina.net/chkui/blog/1920637
正文到此结束
Loading...