本文只貼相關代碼段,完整代碼請移步至本人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.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
*
*/
@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}