spring 使用外部属性文件
一、PropertyPlaceholderConfigurer
spring提供的PropertyPlaceholderConfigurer实现类能够使Bean在配置时引用外部属性文件。
PropertyPlaceholderConfigurer实现了BeanFactoryPostProcessorBean接口,因而也是一个Bean工厂后处理器。
二、PropertyPlaceholderConfigurer的使用
1、xml配置及注解方式:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
pom.xml
name=zhangsan
age=23
my.properties
package test; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Driver {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("my.xml");
User user = context.getBean("user", User.class);
System.out.println(user.getName());
System.out.println(user.getAge());
}
}
class User {
@Value("${name}")
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
java 类
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- spring 引入属性文件 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="classpath:my.properties"
p:fileEncoding="utf-8"/>
<!-- 开启包扫描,因为User类使用到了@Value注解;包扫描不支持裸体类上的注解 -->
<context:component-scan base-package="test"/>
<!-- 使用外部属性文件值赋值 -->
<bean id="user" class="test.User" p:age="${age}"/>
</beans>
spring my.xml
PropertyPlaceholderConfigurer的其他属性:
locations:可以引入多个属性文件
fileEncoding:属性文件的编码格式
order:指定多个属性的优先级
placeholderPrefix:默认值为“${”,可以修改
placeholderSuffix:默认为“}”
除了使用<bean>声明PropertyPlaceholderConfigurer引入属性文件这种方式外,还可以使用另一种简洁的方式;但如果希望自定义一些额外的高级功能,如属性加密、使用数据库表来保存配置信息时,就必须使用<bean>声明PropertyPlaceholderConfigurer的方式
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- spring 引入属性文件 -->
<context:property-placeholder location="my.properties"/>
<!-- 开启包扫描,因为User类使用到了@Value注解;包扫描不支持裸体类上的注解 -->
<context:component-scan base-package="test"/>
<!-- 使用外部属性文件值赋值 -->
<bean id="user" class="test.User" p:age="${age}"/>
</beans>
spring my.xml
2、Java配置及注解方式:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
pom.xml
name=zhangsan
age=23
my.properties
package test; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Driver {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
User user = context.getBean("user", User.class);
System.out.println(user.getName());
System.out.println(user.getAge());
}
}
class User {
@Value("${name}")
private String name;
@Value("${age}")
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
java类
package test; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource; @Configuration
@ComponentScan
public class MyConfig {
@Bean
public User user() {
return new User();
}
@Bean
public PropertyPlaceholderConfigurer PropertyPlaceholderConfigurer() {
PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer();
configurer.setLocation(new ClassPathResource("my.properties"));
return configurer;
} }
java 配置类
三、自定义PropertyPlaceholderConfigurer——支持加密
加密
如果属性信息是数据库用户名、密码等敏感信息,应该使用密文方式。虽说Web应用的客户端用户看不到服务器端的属性文件,但内部人员却可以轻易查看属性文件的内容,这样容易造成数据库访问权限的泄露。
实现
PropertyPlaceholderConfigurer类继承了PlaceholderConfigurerSupport,PlaceholderConfigurerSupport有几个protected的空实现的属性转换方法,专门用于在使用属性之前对属性值进行转换;
所以我们需要自定义PlaceholderConfigurerSupport的实现类并覆盖相应的属性转换方法来代替spring提供的PropertyPlaceholderConfigurer。
信息的加密可分为对称和非对称两种方式,前者加密后可以解密还原,而后者不可以还原;MD5是非对称加密,DES是对称加密,这里使用DES方式。DES加密解密的关键是加密密钥。
demo
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.16.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
pom.xml
name=agyo9QHJ78MfJAfVsP+M2w==
age=ArphqsQ7cdE=
my.properties
package test; import java.security.Key;
import java.security.SecureRandom; import javax.crypto.Cipher;
import javax.crypto.KeyGenerator; import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder; public class DESUtils {
// 指定DES加密解密所用的密钥
private static Key key;
private static String KEY_STR = "myKey";
static {
try {
KeyGenerator generator = KeyGenerator.getInstance("DES");
generator.init(new SecureRandom(KEY_STR.getBytes()));
key = generator.generateKey();
generator = null;
} catch (Exception e) {
throw new RuntimeException(e);
}
} /**
* 对字符串进行DES加密,返回Base64编码的加密字符串
*/
public static String getEncryptString(String str) {
BASE64Encoder base64en = new BASE64Encoder();
try {
byte[] strBytes = str.getBytes("UTF8");
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encryptStrBytes = cipher.doFinal(strBytes);
return base64en.encode(encryptStrBytes);
} catch (Exception e) {
throw new RuntimeException(e);
}
} /**
* 对Base64编码的加密字符串进行DES解密,返回解密后的字符串
*/
public static String getDecryptString(String str) {
BASE64Decoder base64De = new BASE64Decoder();
try {
byte[] strBytes = base64De.decodeBuffer(str);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decryptStrBytes = cipher.doFinal(strBytes);
return new String(decryptStrBytes, "UTF8");
} catch (Exception e) {
throw new RuntimeException(e);
} } /**
* 对入参的字符串加密,并打印密文
*/
public static void main(String[] args) throws Exception {
args = new String[]{"zhangsan", "23"};
if (args == null || args.length < 1) {
System.out.println("请输入要加密的字符,用空格分隔.");
} else {
for (String arg : args) {
System.out.println(arg + ":" + getEncryptString(arg));
}
} //System.out.println(getDecryptString("WnplV/ietfQ="));
//System.out.println(getDecryptString("gJQ9O+q34qk="));
}
}
DESUtils.java
package test; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Driver {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
User user = context.getBean("user", User.class);
System.out.println(user.getName());
System.out.println(user.getAge());
}
}
class User {
@Value("${name}")
private String name;
@Value("${age}")
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Driver.java
package test; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer; public class MyPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
// 需要解密的属性
private String[] encryptPropNames ={"name","age"}; // 解密
@Override
protected String convertProperty(String propertyName, String propertyValue) {
if(isEncryptProp(propertyName)){
String decryptValue = DESUtils.getDecryptString(propertyValue);
System.out.println(decryptValue);
return decryptValue;
}else{
return propertyValue;
}
} /**
* 判断是否是加密的属性
*/
private boolean isEncryptProp(String propertyName){
for(String encryptPropName:encryptPropNames){
if(encryptPropName.equals(propertyName)){
return true;
}
}
return false;
}
}
自定义属性文件加载器
package test; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource; @Configuration
@ComponentScan // 因为用到了@Value注解,所以需要开启扫描
public class MyConfig {
@Bean
public User user() {
return new User();
}
// @Bean
//// public PropertyPlaceholderConfigurer PropertyPlaceholderConfigurer() {
//// PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer();
//// configurer.setLocation(new ClassPathResource("my.properties"));
//// return configurer;
//// }
@Bean
public MyPropertyPlaceholderConfigurer encryptPropertyPlaceholderConfigurer() {
MyPropertyPlaceholderConfigurer configurer = new MyPropertyPlaceholderConfigurer();
configurer.setLocation(new ClassPathResource("my.properties"));
return configurer;
}
}
java配置类
四、属性文件引用属性文件的属性值
Spring允许在xml、java类中使用${xxx}、@Value("${xxx}")引用属性值,也允许在属性文件中使用${xxx}引用其它属性文件的属性值
name=lisi
age=${age}
my.properties
age=18
my2.properties
package test; import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource; @Configuration
public class MyConfig {
@Bean
public User user() {
return new User();
}
@Bean
public PropertyPlaceholderConfigurer PropertyPlaceholderConfigurer() {
PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer();
configurer.setLocations(new ClassPathResource[] {new ClassPathResource("my.properties"),
new ClassPathResource("my2.properties")});
return configurer;
}
}
MyConfig.java
spring 使用外部属性文件的更多相关文章
- Spring 使用外部属性文件配置
1.Spring提供了一个PropertyPlaceholderConfigurer的BeanFactory后置处理器,这个处理器允许用户将Bean的配置的部分内容 移到属性文件中.可以在Bean配置 ...
- Spring使用外部属性文件
一.在 Spring Config 文件中配置 Bean 时,有时候需要在 Bean 的配置里添加 系统部署的细节信息, 如文件路径,数据源配置信息.而这些部署细节实际上需要在配置文件外部来定义. 二 ...
- Spring 应用外部属性文件 配置 context 错误
在Spring配置文件中出现通配符的匹配很全面, 但无法找到元素 'context:property-placeholder' 的声明这个错误,其实主要是我们在引入命名空间时没有正确引入它的DTD解析 ...
- Spring_Bean的作用域---和使用外部属性文件
<!-- 使用 bean的scope属性来配置bean的作用域 singleton:默认值.容器初始时创建bean实例,在整个容器的生命周期内只创建这一个bean单例 prototype:原型的 ...
- Spring - 配置Bean - 自动装配 关系 作用域 引用外部属性文件
1 Autowire自动装配1.1 使用:只需在<bean>中使用autowire元素<bean id="student" class="com.kej ...
- [原创]java WEB学习笔记99:Spring学习---Spring Bean配置:自动装配,配置bean之间的关系(继承/依赖),bean的作用域(singleton,prototype,web环境作用域),使用外部属性文件
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- Spring(十):Spring配置Bean(三)Bean的作用域、使用外部属性文件
Bean的作用域: 支持四种配置,分别是singleton,prototype,request,session. singleton 默认情况下在spring confinguration xml文件 ...
- Spring基础12——使用外部属性文件
1.使用外部属性文件 在配置文件里配置Bean时,有时需要在Bean的配置文件里引入系统部署的细节信息(例如:文件的路径.数据源配置信息等),而这些部署细节实际上需要和bean配置相分离,因为我们修改 ...
- 十八 Spring的JDBC模板:引入外部属性文件
配置外部属性文件 配置文件里引入属性文件,两种方式 第一种: 第二种: 引入属性文件的值: 测试: <?xml version="1.0" encoding="UT ...
随机推荐
- kubernetes集群搭建(8):常用命令
kubectl create -f xxxx.yaml #创建rc.deploy.svc等 kubectl delete -f xxxx.yaml #删除对应的创建 kubectl get pods ...
- CentOS 配置SOCKS5代理服务
SOCKS5 是一个代理协议,它在使用TCP/IP协议通讯的前端机器和服务器机器之间扮演一个中介角色,使得内部网中的前端机器变得能够访问Internet网中的服务器,或者使通讯更加安全 通过yum安装 ...
- 深度学习笔记(七)SSD 论文阅读笔记
一. 算法概述 本文提出的SSD算法是一种直接预测目标类别和bounding box的多目标检测算法.与faster rcnn相比,该算法没有生成 proposal 的过程,这就极大提高了检测速度.针 ...
- 关于resin的illegal utf8 encoding at (190)解决方式
最近在项目开发中,出现了编码异常,内容如下:- illegal utf8 encoding at (190)com.caucho.jsp.JspParseException: illegal utf8 ...
- 06-TypeScript中的表达式
TypeScript中提供了箭头表达式,通过箭头表达式可以简化我们的编码. 1.箭头表达式简化匿名函数 在JS中,我们通常使用匿名函数,匿名函数实际上是赋值给一个变量,常见的写法如下: var sun ...
- Java线程中的join使用实例
JDK中解释为 Waits for this thread to die. 等待本线程结束后,下一个线程才可以运行. 实例要求: 现在有T1.T2.T3三个线程,你怎样保证T2在T1执行完后执行,T3 ...
- c#中打开Excel文档
方法一:(调用Excel的COM组件) 在项目中打开Add Reference对话框,选择COM栏,之后在COM列表中找到"Microsoft Excel 11.0 Object ...
- jQuery 获取对象 根据属性、内容匹配, 还有表单元素匹配
指定元素中包含 id 属性的, 如: $("span[id]") 代码如下: <span id="span1" name="S1"&g ...
- vue 前台传后台
var the = this:let url = "/api/Purchase_Enter/CancelEnter"; let params = { Enter_Id: Enter ...
- SQL语句简单笔记
Create database database name://创建数据库 Show databases dbName: //显示所有数据库 Create table tableName: //创建表 ...