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

作者:cnJun

博客专栏:

https://www.cnblogs.com/cnJun/

本文实现目标

  • 重要的配置信息进行统一管理,例如数据库密码等。
  • 项目端口号、上下文等可以直接设置在配置中心
  • 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}

springboot2 config_toolkit 并且设置全局获取数据GlobalUtil的更多相关文章

  1. 微信小程序云开发-云函数-数据库和云函数获取数据的区别

    一.数据库获取数据 1.1 数据库获取数据的写法 在本地创建的页面js文件中写代码 1.2 数据库获取数据返回数据限制20条 数据库获取数据,每次返回20条数据(数据库有108条数据) 1.3 数据库 ...

  2. DotNetBar 中 SuperGridControl 加载数据、获取数据、设置样式

    1.加载数据 构建列 //加载列 GridColumn gd = new GridColumn(); gd.Name = "第1"; gd.HeaderText = "第 ...

  3. vuex之仓库数据的设置与获取

    如果你之前使用过vue.js,你一定知道在vue中各个组件之间传值的痛苦,在vue中我们可以使用vuex来保存我们需要管理的状态值,值一旦被修改,所有引用该值的地方就会自动更新,那么接下来我们就来学习 ...

  4. jquery获取和设置表单数据

    1.需求 正好做到设置和获取表单数据的功能,做个整理 2.计划安排 3.计划实施 1.获取值 <!--1获取普通文本框的值--> <input type="text&quo ...

  5. 中小研发团队架构实践之生产环境诊断工具WinDbg 三分钟学会.NET微服务之Polly 使用.Net Core+IView+Vue集成上传图片功能 Fiddler原理~知多少? ABP框架(asp.net core 2.X+Vue)模板项目学习之路(一) C#程序中设置全局代理(Global Proxy) WCF 4.0 使用说明 如何在IIS上发布,并能正常访问

    中小研发团队架构实践之生产环境诊断工具WinDbg 生产环境偶尔会出现一些异常问题,WinDbg或GDB是解决此类问题的利器.调试工具WinDbg如同医生的听诊器,是系统生病时做问题诊断的逆向分析工具 ...

  6. 使用Vue.js和Axios从第三方API获取数据 — SitePoint

    更多的往往不是,建立你的JavaScript应用程序时,你会想把数据从远程源或消耗一个[ API ](https:/ /恩.维基百科.org /维基/ application_programming_ ...

  7. hive从查询中获取数据插入到表或动态分区

    Hive的insert语句能够从查询语句中获取数据,并同时将数据Load到目标表中.现在假定有一个已有数据的表staged_employees(雇员信息全量表),所属国家cnty和所属州st是该表的两 ...

  8. jQuery使用ajax跨域请求获取数据

    jQuery使用ajax跨域请求获取数据  跨域是我在日常面试中经常会问到的问题,这词在前端界出现的频率不低,主要原因还是由于安全限制(同源策略, 即JavaScript或Cookie只能访问同域下的 ...

  9. WCF+Restfull服务 提交或获取数据时数据大小限制问题解决方案

    近日在使用wcf的restfull架构服务时遭遇到了提交大数据的问题. 大数据包含两种情形: 1)单条数据量过大. 2)提交或获取的数据条数过多. 在测试时发现,默认设置下当单条JSON数据大于30K ...

随机推荐

  1. pytorch 参数初始化

    https://blog.csdn.net/daydayjump/article/details/80899029

  2. NIO(三)

    使用直接缓冲区完成文件的复制(内存映射文件) package com.cppdy.nio; import java.nio.MappedByteBuffer; import java.nio.chan ...

  3. android入门小结一

    一 Android入门基础:从这里开始 gradle介绍: Android Studio使用Gradle 编译运行Android工程. 工程的每个模块以及整个工程都有一个build.gradle文件. ...

  4. select下拉框可以直接取list里的内容 不用非得转map (不得不承认我是个ZZ,这么简单的问题才反应过来,--^--)

    需求描述:select下拉框的填充项,从后台传来的list中获取 自黑一下:之前有篇随笔,写的是通过map传到前台,在前台的select中的value属性取值 用map的key,而select的tex ...

  5. Imperial roads 非严格次小生成树

    cf测评姬比uva快了五倍... /* 不管这条边是不是在mst上,直接跑lca求出路径上的最大边w即可 ans=mst-w+dist(u,v) */ #include<bits/stdc++. ...

  6. 【转】运维DBA的4大纪律9项注意

    朋友们调侃说,运维是个把脑袋别在裤腰带上的活,更有人说,运维是个把脑袋别在他人裤腰带上的活,苦劳没人认,有锅就有得背! 测试的同学说,“吃瓜群众很难感知运维背后的付出,倒是出了事情更能体现我们的专业性 ...

  7. MySQL数据库权限分类

    一.权限表 mysql数据库中的3个权限表:user .db. host 权限表的存取过程是: 1)先从user表中的host. user. password这3个字段中判断连接的IP.用户名.密码是 ...

  8. python之字符编码

    1.以什么编码存的就以什么编码取出; 内存固定使用unicode编码; 我们可以控制的编码是往硬盘存放或者基于网络传输选择编码. 2.数据是最先产生于内存中,是unicode格式,要想传输需要转成by ...

  9. [转] 谈谈JS中的函数节流

    函数节流的目的 从字面上就可以理解,函数节流就是用来节流函数从而一定程度上优化性能的.例如,DOM 操作比起非DOM 交互需要更多的内存和CPU 时间.连续尝试进行过多的DOM 相关操作可能会导致浏览 ...

  10. YOLO V2 代码分析

    先介绍YOLO[转]: 第一个颠覆ross的RCNN系列,提出region-free,把检测任务直接转换为回归来做,第一次做到精度可以,且实时性很好. 1. 直接将原图划分为SxS个grid cell ...