使用Spring实现属性文件给常量赋值

简介:

测试代码如下;

 

package com.yanek.ioc;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:spring-base.xml"})
public class MyTest3 {

	@Test
	public void test() {

		System.out.println("CHARSET:"+com.yanek.util.ConfigConstants.CHARSET);
		System.out.println("CONNECTTIMEOUT:"+com.yanek.util.ConfigConstants.CONNECTTIMEOUT);
		System.out.println("READTIMEOUT:"+com.yanek.util.ConfigConstants.READTIMEOUT);
	}

}

 

测试输出如下:

 

CHARSET:UTF-8
CONNECTTIMEOUT:1000
READTIMEOUT:5000

 


核心类:

package com.yanek.util;

import java.lang.reflect.Field;
import java.util.Enumeration;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;

/**
 * 自定义PropertyPlaceholderConfigurer返回properties内容
 */ 

public class CustomizedPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
	/**
	 * 属性前缀,可以使用表达式${}。如果使用表达式,表示从属性文件中的字段读取。
	 * 如果为空,表示不使用前缀。
	 */
	private String prefix;
	
	/**
	 * 需要注入的常量类名数组
	 */
	private String[] configureClasses;

	@SuppressWarnings("unchecked")
	protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess, Properties props)
			throws BeansException {
		super.processProperties(beanFactoryToProcess, props);

		if (configureClasses == null) return;
		
		String prefixValue = null;
		if (prefix != null && !prefix.isEmpty()){
			// 如果前缀是表达式,需要从属性中读取
			Pattern p = Pattern.compile("\\$\\{(.*)\\}");
			Matcher matcher = p.matcher(prefix);
			prefixValue = prefix;
			if (matcher.find()) {
				String prefixKey = matcher.group(1);
				prefixValue = props.getProperty(prefixKey);
			}	
		}

		// 遍历多个常量类
		for (int i = 0; i < configureClasses.length; i++) {
			Class c = null;
			try {
				c = Class.forName(configureClasses[i]);
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
				continue;
			}
			
			Field[] fields = c.getFields();

			// 遍历属性列表,注入到常量字段中
			for (Enumeration<?> k = props.propertyNames(); k.hasMoreElements();) {
				String key = (String) k.nextElement();

				// 遍历常量字段数组,找到与属性对应的常量字段
				for (int j = 0; fields != null && j < fields.length; j++) {
					// 取出字段名称,如果有前缀,需要加上前缀
					String keyStr = fields[j].getName();
					if (prefixValue != null && !prefixValue.isEmpty())
						keyStr = prefixValue + "." + fields[j].getName();

					// 判断常量字段是否有属性匹配,不区分大小写。
					if (keyStr.equalsIgnoreCase(key)) {
						// 从属性中取出字段值,并存到字段中
						String value = props.getProperty(key);
						if (value != null) {
							value = value.trim();
							// fields[j].setAccessible(true);
							try {
								if (Integer.TYPE.equals(fields[j].getType())) {
									fields[j].setInt(null, Integer.parseInt(value));
								} else if (Long.TYPE.equals(fields[j].getType())) {
									fields[j].setLong(null, Long.parseLong(value));
								} else if (Short.TYPE.equals(fields[j].getType())) {
									fields[j].setShort(null, Short.parseShort(value));
								} else if (Double.TYPE.equals(fields[j].getType())) {
									fields[j].setDouble(null, Double.parseDouble(value));
								} else if (Float.TYPE.equals(fields[j].getType())) {
									fields[j].setFloat(null, Float.parseFloat(value));
								} else if (Boolean.TYPE.equals(fields[j].getType())) {
									fields[j].setBoolean(null, Boolean.parseBoolean(value));
								} else {
									fields[j].set(null, value);
								}
							} catch (IllegalArgumentException e) {
								e.printStackTrace();
							} catch (IllegalAccessException e) {
								e.printStackTrace();
							}

						}
						break;
					}
				}
			}
		}

	}

	public String getPrefix() {
		return prefix;
	}

	public void setPrefix(String prefix) {
		this.prefix = prefix;
	}

	public String[] getConfigureClasses() {
		return configureClasses;
	}

	public void setConfigureClasses(String[] configureClasses) {
		this.configureClasses = (configureClasses != null)? configureClasses.clone() : null;
	}
	
	public void setConfigureClass(String configureClass) {
		this.configureClasses = new String[] {configureClass};
	}
}


 

package com.yanek.util;

public class ConfigConstants {
	
	
	public static int CONNECTTIMEOUT = 0;
	public static int READTIMEOUT = 0;
	public static String CHARSET = "";

}


属性文件:application.properties

CONNECTTIMEOUT=1000
READTIMEOUT=5000
CHARSET=UTF-8


 spring配置文件:

 

<?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:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
		http://www.springframework.org/schema/context 
 		http://www.springframework.org/schema/context/spring-context-2.5.xsd"
	default-autowire="byName" default-lazy-init="false">
	
	<!-- 从properties文件加载配置信息 -->
	<bean id="propertyPlaceholderConfigurer"
		class="com.yanek.util.CustomizedPropertyPlaceholderConfigurer">
		<property name="locations">
			<list>
				<value>classpath:application.properties</value>
			</list>
		</property>
		<property name="configureClasses">
			<list>
				<value>com.yanek.util.ConfigConstants</value>
			</list>
		</property>		
	</bean>
	
	
</beans>


 

目录
相关文章
|
1月前
|
存储 Java 数据安全/隐私保护
|
9天前
|
JSON 前端开发 Java
Spring第一课,了解IDEA里面的文件,回顾Cookie和Session,获取Session,Cookie,Header的方式
Spring第一课,了解IDEA里面的文件,回顾Cookie和Session,获取Session,Cookie,Header的方式
|
1月前
|
Java Spring
Spring文件配置以及获取
Spring文件配置以及获取
19 0
|
1月前
|
XML Java 数据格式
Spring 属性注入方式
Spring 属性注入方式
17 2
|
1月前
|
Java 数据库连接 数据库
Spring事务简介,事务角色,事务属性
Spring事务简介,事务角色,事务属性
24 2
|
1月前
|
Java Apache Spring
Spring BeanUtils与Apache BeanUtils提供基本属性复制,适用于简单需求
【5月更文挑战第4天】Spring BeanUtils与Apache BeanUtils提供基本属性复制,适用于简单需求;Cglib BeanCopier用于转换为Cglib代理对象;Apache PropertyUtils处理属性操作;Dozer支持复杂对象映射。选择工具取决于具体需求,如需精细控制或对象映射,推荐Dozer或Apache PropertyUtils。Apache BeanUtils可能因潜在的封装性破坏被禁用。
29 3
|
1月前
|
Java 开发者 Spring
Spring Boot中的资源文件属性配置
【4月更文挑战第28天】在Spring Boot应用程序中,配置文件是管理应用程序行为的重要组成部分。资源文件属性配置允许开发者在不重新编译代码的情况下,对应用程序进行灵活地配置和调整。本篇博客将介绍Spring Boot中资源文件属性配置的基本概念,并通过实际示例展示如何利用这一功能。
30 1
|
1月前
|
JSON Java 数据库连接
属性注入掌握:Spring Boot配置属性的高级技巧与最佳实践
属性注入掌握:Spring Boot配置属性的高级技巧与最佳实践
30 1
|
1月前
|
XML Java 关系型数据库
注解驱动事务:Spring中基于注解的事务属性配置详解
注解驱动事务:Spring中基于注解的事务属性配置详解
45 0
注解驱动事务:Spring中基于注解的事务属性配置详解
|
1月前
|
存储 JavaScript 前端开发
Spring Boot + Vue: 实现文件导入导出功能
本文介绍了使用Spring Boot和Vue实现文件导入导出的步骤。在后端,Spring Boot通过`MultipartFile`接收上传文件,保存至服务器,并使用`ResponseEntity`提供文件下载。前端部分,Vue项目借助`axios`发送HTTP请求,实现文件选择、上传及下载功能。这种前后端分离的实现方式提高了应用的可维护性和可扩展性。
88 2