springboot2 config_toolkit 并且设置全局获取数据GlobalUtil

魏兴邦
2023-12-01

本文只贴相关代码段,完整代码请移步至本人github,若是喜欢,可以star给予支持

作者:o_cYj
博客专栏:
https://blog.csdn.net/o_cYj

目录

本文实现目标

  • 重要的配置信息进行统一管理,例如数据库密码等。
  • 项目端口号、上下文等可以直接设置在配置中心
  • xml、properties、java、ftl文件可以轻松获取到配置中心的配置信息

前期工作

对于config_toolkit及zookeeper的安装及创建节点请自己查阅相关资料
config_toolkit初始配置可以参考https://github.com/dangdangdotcom/config-toolkit

具体实现

启动项设置

-Dconfig.zookeeper.connectString=localhost:2181
-Dconfig.rootNode=/project/module
-Dconfig.version=1.0.0
-Dconfig.groupName=sb2

其中
connectString为zookeeper的连接地址加端口号
rootNode为在zookeeper创建的根节点
version为版本号
groupName是你自己创建的组管理名称

导入相关jar包

<dependency>
    <groupId>com.dangdang</groupId>
    <artifactId>config-toolkit</artifactId>
    <version>3.3.2-RELEASE</version>
</dependency>

applicationContext.xml

在applicationContext.xml中引入config_toolkit的相关配置

<?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:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"

       default-lazy-init="true">

    <description>Spring公共配置</description>

    <bean id="configProfile" class="com.dangdang.config.service.zookeeper.ZookeeperConfigProfile">
        <constructor-arg name="connectStr"
                         value="#{systemProperties['config.zookeeper.connectString']}" />
        <constructor-arg name="rootNode" value="#{systemProperties['config.rootNode']}" />
        <constructor-arg name="version" value="#{systemProperties['config.version']}" />
    </bean>

    <bean id="configGroupSources" class="com.dangdang.config.service.support.spring.ConfigGroupSourceFactory" factory-method="create">
        <constructor-arg name="configGroups">
            <list>
                <bean class="com.dangdang.config.service.zookeeper.ZookeeperConfigGroup" c:configProfile-ref="configProfile" c:node="#{systemProperties['config.groupName']}"  c:enumerable="true"  />
                <bean class="com.dangdang.config.service.zookeeper.ZookeeperConfigGroup"  c:configProfile-ref="configProfile" c:node="apps_common"  c:enumerable="true" />
                <bean class="com.dangdang.config.service.file.FileConfigGroup">
                    <constructor-arg name="configProfile">
                        <bean class="com.dangdang.config.service.file.FileConfigProfile">
                            <constructor-arg name="fileEncoding" value="utf-8" />
                            <constructor-arg name="contentType" value="properties" />
                        </bean>
                    </constructor-arg>
                    <constructor-arg name="location" value="classpath:application.properties" />
                    <constructor-arg name="enumerable" value="true"/>
                </bean>
            </list>
        </constructor-arg>
    </bean>

    <bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
        <property name="order" value="1" />
        <property name="ignoreUnresolvablePlaceholders" value="true" />
        <property name="propertySources" ref="configGroupSources" />
    </bean>

</beans>
  • 其中使用systemProperties获取的参数值为上面启动设置里面的值,这里可以根据自己的情况进行修改,可以直接赋值,也可以写在
  • application.properties里面获取
  • 配置中还引入了application.properties
  • 读取参数时是按照configGroups中的顺序来读取,所以会优先使用这里面前面组中所拥有的参数
  • 在xml中我们注入了configGroupSources的bean,我们后面主要从此bean中获取相关的数据

完成到这里,我们如果在配置中心配置了相关的server.portserver.contextPath,就已经可以修改启动时的端口号和上下文了

上下文工具文件 SpringContextUtil.java

此文件用于获取上面设置的configGroupSources

package com.chenyingjun.springboot2.utils;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;

/**
 * 静态获取Bean
 *
 * @author chenyingjun
 * @version 2018年08月24日
 * @since 1.0
 *
 */
@Configuration
public class SpringContextUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext;

    /**
     * 重写上下文信息
     * @param applicationContext 上下文
     * @throws BeansException e
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        SpringContextUtil.applicationContext = applicationContext;
    }

    /**
     * 获取上下文
     * @return 上下文
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 获取指定的bean
     * @param name bean名
     * @return bean对象
     * @throws BeansException e
     */
    public static Object getBean(String name) throws BeansException {
        try {
            return applicationContext.getBean(name);
        } catch (Exception e) {
            throw new RuntimeException("获取的Bean不存在!");
        }
    }

    public static <T> T getBean(String name, Class<T> requiredType)
            throws BeansException {
        return applicationContext.getBean(name, requiredType);
    }

    public static boolean containsBean(String name) {
        return applicationContext.containsBean(name);
    }

    public static boolean isSingleton(String name)
            throws NoSuchBeanDefinitionException {
        return applicationContext.isSingleton(name);
    }

    public static Class<? extends Object> getType(String name)
            throws NoSuchBeanDefinitionException {
        return applicationContext.getType(name);
    }

    public static String[] getAliases(String name)
            throws NoSuchBeanDefinitionException {
        return applicationContext.getAliases(name);
    }

}

配置参数获取文件PropertiesLoaderUtil.java

package com.chenyingjun.springboot2.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;

import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * 配置参数信息
 * @author chenyingjun
 * @date 2018年8月24日
 */
public class PropertiesLoaderUtil {

    /**
     * 日志
     */
    private static Logger logger = LoggerFactory.getLogger(PropertiesLoaderUtil.class);

    /**
     * properties
     */
    private MutablePropertySources propertySources;

    /**
     * 加载配置信息
     */
    public PropertiesLoaderUtil() {
        try {
            this.propertySources = (MutablePropertySources) SpringContextUtil.getBean("configGroupSources");
        } catch (Exception var3) {
            logger.error("没有配置统一配置服务");
        }
    }

    /**
     * 根据key值获取配置信息
     * @param key key
     * @return 配置信息
     */
    private String getValue(String key) {
        String systemProperty = System.getProperty(key);
        if (systemProperty != null) {
            return systemProperty;
        } else {
            if (this.propertySources != null) {
                Iterator iter = this.propertySources.iterator();

                while(iter.hasNext()) {
                    PropertySource<?> str = (PropertySource)iter.next();
                    if (str.containsProperty(key)) {
                        return str.getProperty(key).toString();
                    }
                }
            }
            return null;
        }
    }

    /**
     * 根据key值获取配置信息
     * @param key key
     * @return 配置信息
     */
    public String getProperty(String key) {
        String value = this.getValue(key);
        if (value == null) {
            throw new NoSuchElementException();
        } else {
            return value;
        }
    }

    /**
     * 根据key值获取配置信息
     * @param key key
     * @param defaultValue 默认值
     * @return 配置信息
     */
    public String getProperty(String key, String defaultValue) {
        String value = this.getValue(key);
        return value != null ? value : defaultValue;
    }
}

使用于获取数据后全局使用的工具类GlobalUtil.java

package com.chenyingjun.springboot2.utils;

/**
 * 配置信息获取
 * @author chenyingjun
 * @date 2018年8月13日
 */
public class GlobalUtil {

    /**
     * 配置参数信息
     */
    private static PropertiesLoaderUtil propertiesLoaderUtil;

    /**
     * 构建函数
     */
    public GlobalUtil() {
    }

    /**
     * 根据key值获取配置信息
     * @param key key
     * @return 配置信息
     */
    public static String getConfig(String key) {
        return getPropertiesLoaderUtil().getProperty(key);
    }

    /**
     * 根据key值获取配置信息
     * @param key key
     * @param defaultValue 默认值
     * @return 配置信息
     */
    public static String getConfig(String key, String defaultValue) {
        return getPropertiesLoaderUtil().getProperty(key, defaultValue);
    }

    public static int getIntConfig(String key) {
        return Integer.valueOf(getConfig(key)).intValue();
    }

    public static int getIntConfig(String key, int defaultValue) {
        return Integer.valueOf(getConfig(key, String.valueOf(defaultValue))).intValue();
    }

    public static boolean getBooleanConfig(String key) {
        return Boolean.valueOf(getConfig(key)).booleanValue();
    }

    public static boolean getBooleanConfig(String key, boolean defaultValue) {
        return Boolean.valueOf(getConfig(key, String.valueOf(defaultValue))).booleanValue();
    }

    public static long getLongConfig(String key) {
        return Long.valueOf(getConfig(key)).longValue();
    }

    public static long getLongConfig(String key, long defaultValue) {
        return Long.valueOf(getConfig(key, String.valueOf(defaultValue))).longValue();
    }


    /**
     * 加载配置文件
     * @return 配置信息
     */
    private static PropertiesLoaderUtil getPropertiesLoaderUtil() {
        if (null == propertiesLoaderUtil) {
            propertiesLoaderUtil =  new PropertiesLoaderUtil();
        }
        return propertiesLoaderUtil;
    }
}

config_toolkit数据使用范例

此时,我们可以自由的对配置中心里面的数据进行获取了

java类内获取参数示例

@Value("${systemProfiles.title}")
private String testConfigValue;
String title = GlobalUtil.getConfig("systemProfiles.title", "无值");

properties文件获取参数示例

spring.redis.host=${redis.host}
spring.redis.port=${redis.port}

xml文件获取参数示例

<constructor-arg index="2" value="${redis.port}"  name="port" type="int"/>

freemarker获取参数

需在自行定义工具配置类MyFreeMarkerConfig.java

package com.chenyingjun.springboot2.config;

import com.chenyingjun.springboot2.utils.GlobalUtil;
import freemarker.template.Configuration;
import freemarker.template.TemplateModelException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * FreeMarker工具类配置
 * 
 * @author chenyingjun
 * @since 1.0
 * @version 2018年8月15日 chenyingjun
 */
@Component
public class MyFreeMarkerConfig {

    /** Logger */
    private final Logger logger = LoggerFactory.getLogger(MyFreeMarkerConfig.class);

    /** Configuration */
    @Autowired
    private Configuration freeMarkerConfiguration;

    /**
     * 配置工具类
     */
    @PostConstruct
    public void freemarkerConfig() {
        try {
            freeMarkerConfiguration.setSharedVariable("global", new GlobalUtil());
        } catch (TemplateModelException e) {
            logger.error(e.toString(), e);
        }
    }

}

这样,我们就能在ftl页面中获取我们需要的参数了

freemarker文件获取参数示例

${global.getConfig("systemProfiles.title")?html}
 类似资料: