本文实现目标
重要的配置信息进行统一管理,例如数据库密码等。
项目端口号、上下文等可以直接设置在配置中心
xml、properties、java、ftl文件可以轻松获取到配置中心的配置信息
前期工作
对于config_toolkit及zookeeper的安装及创建节点请自己查阅相关资料
具体实现
启动项设置
-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.port
和server.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 * */@Configurationpublic 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 */@Componentpublic 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}
作者:yingjunchen
链接:https://www.jianshu.com/p/b80848f5041a