spring3.1+项目中创建PropertiesUtil工具类读取配置文件

一、背景
我们都知道spring可以帮我们读取properties配置文件,我们只需要简单配置一行:

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

就能在java代码中使用@Value("${xxxx}")美滋滋的读取配置文件,但是如果有需要在java代码中使用类似PropertiesUtil.getProperties(“xxxx”)的方式去读取配置,有几种实现方式呢?
1、最笨的办法,直接读取指定文件名的配置,很明显太死板,不灵活,不可取
2、依靠spring的properties解析类自定义PropertiesUtil

二、本文主要讲第二种方式的实现哈,注意!在spring3.1之前是使用PropertyPlaceholderConfigurer,而spring3.1版本之后加载properties配置的类叫PropertySourcesPlaceholderConfigurer,如果你的项目还是使用的老的版本或老的配置方式,可以参考这篇文章的配置方式:spring3.1之前的配置方式

三、接下来让我们看看在spring3.1+版本中,重写PropertySourcesPlaceholderConfigurer类来创建PropertiesUtil的实现方式
1、spring3.1之前是通过新建一个类并继承PropertyPlaceholderConfigurer类再重写processProperties方法来实现的,但在PropertySourcesPlaceholderConfigurer中这个方法已经被弃用,所以直接拷贝老的实现换个继承的类来实现是不可取的

2、通过阅读PropertySourcesPlaceholderConfigurer类的源码不难发现,它加载配置文件的核心方法是postProcessBeanFactory(),通过debug可以进一步了解到读取的配置都在该类的appliedPropertySources中,实现思路就有了!我们新建一个类继承PropertySourcesPlaceholderConfigurer并重写它的postProcessBeanFactory()方法,将配置都加载到一个map中,然后提供一个PropertiesUtil的类来从这个map种读取配置就好了,上才艺:

public class PropertiesUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(PropertiesUtil.class);

    private static Map<String, Object> propertiesMap;

    public static String getProperties(String name) {
        Object value = propertiesMap.get(name);
        return value != null ? String.valueOf(value) : null;
    }

    public static void initPropertiesMap(PropertySourcesPlaceholderConfigurer propertyConfigurer) {
        if (null == propertiesMap) {
            propertiesMap = new HashMap<>();
        }
        // 装载远程配置,笔者项目中使用nacos作为配置中心,没有的可以忽略或去掉这段代码
        PropertySources appliedPropertySources = propertyConfigurer.getAppliedPropertySources();
        PropertySource<?> environmentPropertySource = appliedPropertySources
                .get(PropertySourcesPlaceholderConfigurer.ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME);
        StandardEnvironment environment = (StandardEnvironment) environmentPropertySource.getSource();
        MutablePropertySources mutablePropertySources = environment.getPropertySources();
        mutablePropertySources.forEach(propertySource -> {
            if (propertySource.getSource() instanceof Map) {
                propertiesMap.putAll((Map<? extends String, ?>) propertySource.getSource());
            }
        });

        // 装载本地配置
        PropertiesPropertySource localPropertySource = (PropertiesPropertySource) appliedPropertySources
                .get(PropertySourcesPlaceholderConfigurer.LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME);
        if (localPropertySource != null) {
            propertiesMap.putAll(localPropertySource.getSource());
        }

    }

    public static void reloadConfig(String config) {
        if (StrUtil.isBlank(config)) {
            return;
        }
        Properties properties = new Properties();
        try {
            properties.load(new StringReader(config));
        } catch (IOException e) {
            LOGGER.error("load config error. ", e);
            return;
        }
        Set<Map.Entry<Object, Object>> entries = properties.entrySet();
        entries.forEach(i -> {
            propertiesMap.put(String.valueOf(i.getKey()), i.getValue());
            LOGGER.debug("key={}, value={} updated", i.getKey(), i.getValue());
        });
    }
}

上面的工具类封装了初始化map及刷新配置的方法,刷新配置用于从配置中心拉取到更新,同步更新map中的属性,实现实时更新配置,定义PropertySourcesPlaceholderConfigurer的实现类:

public class PropertyConfigurer extends PropertySourcesPlaceholderConfigurer {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        super.postProcessBeanFactory(beanFactory);
        PropertiesUtil.initPropertiesMap(this);
    }

}

四、最后就是要在spring的配置文件中使用自定义的类来加载配置了!

	<bean class="com.lieni.core.web.config.PropertyConfigurer">
		<property name="locations">
			<list>
				<value>classpath:properties/*.properties</value>
				<value>classpath:properties/*/*.properties</value>
			</list>
		</property>
		<property name="fileEncoding" value="UTF-8" />
	</bean>

五、java代码中使用

String value = PropertiesUtil.getProperties("key");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值