说说在Spring中如何引用外部属性文件的方法

进行数据源或者 FTP 服务器等资源配置时,我们可以将这些配置信息放到一个独立的外部属性文件中,并在 Spring 配置文件中通过形如 ${user}、${password} 的占位符方式来引用属性文件中的属性项 。

这种方式的配置有两个好处:

  1. 减少了维护的工作量 - 资源的配置信息可以被多个应用共享,如果资源的配置信息发生了变更,那么我们只需要调整这个独立的配置文件就可以啦。
  2. 部署更加简单 - 通过一个独立的属性文件来存放这些配置信息,则部属人员只需要调整这个属性文件即可,无须关注结构复杂、信息量大的 Spring 配置文件咯。

Spring 提供了一个 PropertyPlaceholderConfigurer ,它能够在装载 Bean 时引用外部属性文件 。PropertyPlaceholderConfigurer 实现了 BeanFactoryPostProcessorBean 接口,所以它是一个 Bean 工厂后处理器。

1 基本引用

1.1 PropertyPlaceholderConfigurer 方式(XML 配置)

假设需要在 Bean 中定义一个数据源:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
 destroy-method="close"
 p:driverClassName="com.mysql.jdbc.Driver"
 p:url="jdbc:mysql://127.0.0.1:3306/spring4"
 p:username="root"
 p:password=""/>

这里把驱动类名 、JDBC 的 URL 以及数据库的用户名和密码都直接写在了 XML 中 。 这样在部署时,如果需要改动数据库的配置信息,那么首先需要先找到这个 XML,然后再进行修改,不方便 。

建议将这些信息抽取到一个配置文件中,假设取名为 system.priperties:

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/spring4
username=root
password=

属性文件可以定义多个属性,每个属性的格式为:属性名=属性值

spring 配置:

<!-- 引入外部属性文件-->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
  p:location="classpath:system.properties"
  p:fileEncoding="utf-8"/>

<!-- 数据源-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
  destroy-method="close"
  p:driverClassName="${driverClassName}"
  p:url="${url}"
  p:username="${username}"
  p:password="${password}"/>

通过这样配置之后,我们在部署时,仅需关注这个配置文件即可。

PropertyPlaceholderConfigurer 属性说明如下:

属性 说明
location 指定属性文件的路径。
locations 指定多个属性文件的路径。
fileEncoding 文件的编码格式,如果不指定,那么 Spring 会使用操作系统的默认编码格式来读取文件的内容。
order 如果配置文件中定义了多个 PropertyPlaceholderConfigurer ,那么可以通过这个属性来指定优先顺序。
placeholderPrefix 占位符后缀,默认为 ${。
placeholderSuffix 占位符前缀,默认为 }。

1.2 context:property-placehoder 方式(XML 配置)

可以使用 context 命名空间来定义属性文件,相对于 PropertyPlaceholderConfigurer 的配置方式,这种方式更优雅。

<context:property-placeholder location="classpath:system.properties"
         file-encoding="utf-8"/>

这种方式虽然如果希望对属性进行加密或者使用数据库表保存配置信息等的高级功能,就必须扩展 PropertyPlaceholderConfigurer 的类,然后采用之前所说的 Bean 配置方式 。

1.3 @value 方式(基于注解或 JAVA 类的配置)

基于注解的 Bean 可以通过 @Value 注解为 Bean 的成员变量或者方法入参自动注入属性值 。

@Component
public class CustomDataSource {

 @Value("${driverClassName}")
 private String driverClassName;

 @Value("${url}")
 private String url;

 @Value("${username}")
 private String username;

 @Value("${password}")
 private String password;

 //省略 getter/setter
}

而基于 JAVA 类注解 @Configuration 的类本身就标注了 @Component,所以它引用属性的方式和基于注解配置的引用方式是一样的 。

注意:使用过程中要确保所引用的属性值在属性文件中存在并且类型匹配,否则会抛出异常。

2 加密属性值

对于那些不敏感的属性信息,在属性文件中以明文形式出现是合理的,但是如果属性信息是敏感信息(比如数据库用户名和密码等),建议以密文的方式保存 。 因为如果敏感信息密文保存,那么任何拥有服务器登陆权限的人就有可能看到机密信息,从而影响系统安全。

对于那些对安全要求特别高的系统(银行、公安系统等),这些敏感信息应该只掌握在少数特定的维护人员手里。所以,我们需要对这些信息进行加密,Spring 容器读取文件后,再对其进行解密。

PropertyPlaceholderConfigurer 继承自 PlaceholderConfigurerSupport 类,后者设计了一些方法,用于在属性被使用之前对它们进行转换:

方法 说明
convertProperty(String propertyName, String propertyValue) 加载并读取每一个属性值时,都会调用此方法对其进行转换处理。
String convertPropertyValue(String originalValue) 与前一个方法功能相似,只不过参数只传入了属性值。
void convertProperties(Properties props) 转换所有的属性值。

默认情况下,这三个都是空方法,我们可以扩展 PropertyPlaceholderConfigurer ,覆盖相应的转换方法,从而支持带加密后的属性值文件。

2.1 DES 加密解密工具类

信息的加密分为对称和非对称两种方式, 对称表示加密后的信息可以解密出来,而非对称方式则不能根据加密后的信息解密为原值 。 MD5 属于非对称加密, DES 属于对称加密 。所以这里我们使用 DES 加密属性值;读取属性值时,再使用 DES 进行解密 。

DES 加密解密工具类源代码请点击这里

DES 加解密使用说明:

我们使用 DES 加解密工具,通过命令行的方式,对数据库的账号与密码进行加密;接着,把加密后的字符串写入 system.properties,形如:

username=q5L+2PPrsPQ=
password=UdyjsvkXc/Q=

2.2 对属性文件的值进行加密

首先自定义属性配置器,支持解密转换:

public class CustomPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {

 /**
  * DES 密钥
  */
 private static final String KEY_STR = "123456";

 /**
  * 值加密过的属性名称组
  */
 public static final String[] ENCRYPT_PROPERTY_NAMES = new String[]{"username", "password"};

 @Override
 protected String convertProperty(String propertyName, String propertyValue) {
  if (!isDecrypt(propertyName)) {
   return propertyValue;
  }

  //解密
  return new DES(KEY_STR).decrypt(propertyValue);
 }

 /**
  * 是否需要解密
  *
  * @param propertyName 属性名称
  * @return
  */
 private boolean isDecrypt(String propertyName) {
  return ArrayUtils.contains(ENCRYPT_PROPERTY_NAMES, propertyName);
 }
}

注意:

  1. 这里的 DES 密钥必须与之前加密的密钥相同。
  2. ArrayUtils 来源于 commons-lang3。

然后通过 <bean> 的方式来配置自定义的属性文件:

 <bean class="net.deniro.spring4.properties.CustomPropertyPlaceholderConfigurer"
 p:location="classpath:system.properties"
 p:fileEncoding="utf-8"/>

这样,Spring 容器就可以加载被加密过的属性文件啦,是不是很简单呀
O(∩_∩)O哈哈~

3 对自身的引用

Spring 既允许在 Bean 定义中通过 ${propName}引用属性的值,也允许在属性文件中使用 ${propName} 实现属性之间的相互引用 。

database=spring4

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/${database}

这里通过 ${database}引用了另外一个属性的值(数据库实例名)。因此,对于一些复杂的属性,我们可以通过这种方式将属性变化的部分抽取出来,从而实现配置的最小化 。

注意:如果一个属性值太长,我们可以在每一行的最后加上 “\”,就可以把属性值划分为多行,就像这样:

profile.jdbc.url=jdbc:mysql://127.0.0.1:3306/dbName?useUnicode=true&characterEncoding\
 =UTF-8\
 &zeroDateTimeBehavior=convertToNull

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 说说在Spring中如何引用外部属性文件的方法

    进行数据源或者 FTP 服务器等资源配置时,我们可以将这些配置信息放到一个独立的外部属性文件中,并在 Spring 配置文件中通过形如 ${user}.${password} 的占位符方式来引用属性文件中的属性项 . 这种方式的配置有两个好处: 减少了维护的工作量 - 资源的配置信息可以被多个应用共享,如果资源的配置信息发生了变更,那么我们只需要调整这个独立的配置文件就可以啦. 部署更加简单 - 通过一个独立的属性文件来存放这些配置信息,则部属人员只需要调整这个属性文件即可,无须关注结构复杂.信

  • Spring IOC容器基于XML外部属性文件的Bean管理

    目录 Spring IOC Bean管理XML 一.常规配置方法 1. 引入依赖 2. xml 文件配置数据库连接池 二.引入外部属性文件来配置数据库连接池 1. 创建外部文件 2. 引入外部文件到xml配置文件中 3. 引用外部文件里的属性 Spring IOC Bean管理XML 有时候,为了灵活方便,我们会把某些固定的数据存放到文件里,然后去读取里面的内容来使用. 比如数据库的连接信息,这些内容就可以放到 properties 文件中,然后使用 xml 配置文件去读取里面的内容,完成需要的

  • 详解Spring中的Environment外部化配置管理

    目录 profiles ProfileService 声明一个配置类 定义测试方法 profiles总结 Properties environment的应用 指定profile属性 @Value注解的使用 SpringEnvironment原理设计 Environment的中文意思是环境,它表示整个spring应用运行时的环境信息,它包含两个关键因素 profiles properties profiles profiles这个概念相信大家都已经理解了,最常见的就是不同环境下,决定当前sprin

  • Spring引入外部属性文件配置数据库连接的步骤详解

    直接配置数据库的信息 xml配置文件直接配置: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.sprin

  • JS动态插入脚本和插入引用外部链接脚本的方法

    在日常开发中,经常遇到 js 动态插入脚本 . 什么是 js 动态插入脚本 ? 指的是在页面加载时不存在,但将来的某一时刻通过修改该 DOM 动态添加的脚本.和操作 HTML 元素一样. js 动态插入脚本也有两种方式:插入 JavaScript 代码和插入外部文件. 一.直接插入 javascript 代码 <script type="text/javascript"> function sayHi() { alert("hi"); } </sc

  • spring中@Reference注入为空的解决方法

    线上发生事故了 前天晚上上线一波,发生了一个挺有意思的事,昨天复盘了一下,今天分享一下. 晚上的时候,我负责的系统和收银系统同时上线一波(用的是Dubbo).然后很神奇的事情发生了,收银系统用@Reference注解注入我的接口,然后这个接口的实现类居然为空. 其实我们当时没排查出来是什么原因? 重启了一下就好了,毕竟重启大法好. 但本着不能给用户充钱的路上造成阻碍,还是要排查一波这个代理对象为空是如何造成的. 线上dubbo的版本为2.8.9,注意包名是(com.alibaba) 为了方便大家

  • 微信小程序wxss如何引用外部CSS文件以及iconfont

    起因 小程序引入外部文件的方式是:@import "*/*.wxss"; 因为业务需要,正在开发的小程序中需要使用iconfont,很容易想到了H5的引入方式: ```` @font-face {font-family: "iconfont"; src: url('iconfont.eot?t=1485242349767'); /* IE9*/ src: url('iconfont.eot?t=1485242349767#iefix') format('embedd

  • java中读写Properties属性文件公用方法详解

    前言 大家都知道Java中有个比较重要的类Properties(Java.util.Properties),主要用于读取Java的配置文件,各种语言都有自己所支持的配置文件,配置文件中很多变量是经常改变的,这样做也是为了方便用户,让用户能够脱离程序本身去修改相关的变量设置.像Python支持的配置文件是.ini文件,同样,它也有自己读取配置文件的类ConfigParse,方便程序员或用户通过该类的方法来修改.ini配置文件.在Java中,其配置文件常为.properties文件,格式为文本文件,

  • Spring实战之设置普通属性值的方法示例

    本文实例讲述了Spring实战之设置普通属性值的方法.分享给大家供大家参考,具体如下: 一 配置 <?xml version="1.0" encoding="GBK"?> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.springframework.org/schema/beans" xsi:sch

  • spring中使用mybatis plus连接sqlserver的方法实现

    本文主要关注如何使用mybatis/mybatis plus连接SQL Server数据库,因此将省略其他项目配置.代码. 框架选择 应用框架:spring boot ORM框架:mybatis plus(对于连接数据库而言,mybatis和mybatis plus其实都一样) 数据库连接池:druid pom依赖 此处仅给出我的配置,mybatis/druid请依据自己项目的需要进行选择. 方便起见我用的是mybatis plus <!--mybatis plus --> <depen

随机推荐