携程官网对apollo的使用讲解了很多种方式的使用,但是感觉一些细节还是没讲全,特别是eureka配置中心地址的配置

这里对springboot整合apollo说一下

>SpringBoot启动vm参数添加:

-Ddev_meta=http://18.16.200.107:8080 -Denv=DEV

其中-Ddev-meta连接的是配置管理eureka的url地址

-Denv配置的是具体的环境

>也可以在C:\opt\settings\server.properties中添加环境配置:

env=DEV

这个配置文件里面只能配置环境,不能配置url

>第一步配置app.id,在META-INF/app.properties里面添加app.id,类型字符串

代码:



package com.qhong.springboot;

import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.model.ConfigChange;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfig;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
* 使用Java Config方式
* 使用@ApolloConfig自动注入Config对象
* 使用@ApolloConfigChangeListener自动注入ConfigChangeListener对象
* 当监听到属性值发生变化后使用Config API修改属性值
*/
@ToString
@Component
@ConfigurationProperties
public class JavaConfigSample {
/**
* @ApolloConfig用来自动注入Config对象
*/
@ApolloConfig
private Config config;
/**
* @ApolloConfigChangeListener用来自动注册ConfigChangeListener
*/
@ApolloConfigChangeListener
private void someOnChange(ConfigChangeEvent changeEvent) {
changeEvent.changedKeys().forEach(key ->{
ConfigChange change = changeEvent.getChange(key);
System.out.println(String.format("Found JavaConfigSample change - key: %s, oldValue: %s, newValue: %s, changeType: %s", change.getPropertyName(), change.getOldValue(), change.getNewValue(), change.getChangeType()));
});
}


@Value("${timeout:100}")
private int timeout;
private int batch;

@Value("${batch:200}")
public void setBatch(int batch) {
this.batch = batch;
}

public int getTimeout() {
if(config!=null) {
return config.getIntProperty("timeout", 100);
}else{
return timeout;
}
}

public int getBatch() {
return this.batch;
}
}


这个类里面timeout获取值的方式直接调用getIntProperty



package com.qhong.springboot;

import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.model.ConfigChange;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfig;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
* 使用Spring Boot ConfigurationProperties方式
* <pre>
* redis.cache.enabled = true
* redis.cache.expireSeconds = 100
* redis.cache.clusterNodes = 1,2
* redis.cache.commandTimeout = 50
* redis.cache.someMap.key1 = a
* redis.cache.someMap.key2 = b
* redis.cache.someList[0] = c
* redis.cache.someList[1] = d
* </pre>
*/
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Component
@ConfigurationProperties(prefix = "redis.cache")
@EnableApolloConfig("application")
public class ConfigurationPropertiesSample {

private int expireSeconds;
private String clusterNodes;
private int commandTimeout;

private Map<String, String> someMap = Maps.newLinkedHashMap();
private List<String> someList = Lists.newLinkedList();

@PostConstruct
private void initialize() {
System.out.println(String.format(
"SampleRedisConfig initialized - expireSeconds: {}, clusterNodes: {}, commandTimeout: {}, someMap: {}, someList: {}",
expireSeconds, clusterNodes, commandTimeout, someMap, someList));
}

/**
* @ApolloConfig用来自动注入Config对象
*/
@ApolloConfig("application")
private Config config;
/**
* @ApolloConfigChangeListener用来自动注册ConfigChangeListener
*/
@ApolloConfigChangeListener("application")
private void someOnChange(ConfigChangeEvent changeEvent) {
changeEvent.changedKeys().forEach(key ->{
ConfigChange change = changeEvent.getChange(key);
System.out.println(String.format("Found change - key: %s, oldValue: %s, newValue: %s, changeType: %s", change.getPropertyName(), change.getOldValue(), change.getNewValue(), change.getChangeType()));
});
}
}


这个是各种属性类型的使用

apollo配置中心文本格式:



esb.app.url = http://18.16.200.10:3000/
endpoints.shutdown.enabled = true
endpoints.shutdown.sensitive = false
spring.http.multipart.maxFileSize = 100Mb
spring.http.multipart.max-request-size = 100Mb

timeout = 120
batch = 222
redis.cache.enabled = false
redis.cache.expireSeconds = 154
redis.cache.clusterNodes = 1,2,3,4
redis.cache.commandTimeout = 60
redis.cache.someMap.key1 = a
redis.cache.someMap.key2 = b
redis.cache.someList[0] = c
redis.cache.someList[1] = d


上面两种都是默认的namespace,为application

下面添加一个datasource命名空间类型的类



package com.qhong.springboot;

import com.ctrip.framework.apollo.Config;
import com.ctrip.framework.apollo.model.ConfigChange;
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfig;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
import lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

/**
* Created by qhong on 2018/5/8 16:10
**/
@ToString
@Component
@Data
@ConfigurationProperties
@EnableApolloConfig("datasource")
public class DataSourceConfig {
// 动态配置从esb config读取
private String url;
private String username;
private String password;
private String driverClassName;

/**
* @ApolloConfig用来自动注入Config对象
*/
@ApolloConfig("datasource")
private Config config;

/**
* @ApolloConfigChangeListener用来自动注册ConfigChangeListener
*/
@ApolloConfigChangeListener("datasource")
private void someOnChange(ConfigChangeEvent changeEvent) {
changeEvent.changedKeys().forEach(key ->{
ConfigChange change = changeEvent.getChange(key);
System.out.println(String.format("Found datasource change - key: %s, oldValue: %s, newValue: %s, changeType: %s", change.getPropertyName(), change.getOldValue(), change.getNewValue(), change.getChangeType()));
});
}

}


注意EnableApolloConfig中定义datasource命名空间

上面类的具体文本:



url = jdbc:mysql://120.26.130.187:3306/huishi-server?useUnicode=true&characterEncoding=utf-8&useSSL=false
username = root
password = jsy2016memeda
driverClassName = com.mysql.jdbc.Driver


当然也可以使用ApolloConfig这个定义datasource命名空间的,然后一个个getProperty来获取值,就是有点不方便。

下面使用SpringBoot启动:



package com.qhong.springboot;

import com.google.common.base.Charsets;
import com.google.common.base.Strings;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication(scanBasePackages = {"com.qhong.springboot"})
public class Application {
public static void main(String[] args) throws Exception {
ApplicationContext context = new SpringApplicationBuilder(Application.class).run(args);
JavaConfigSample javaConfigSample = context.getBean(JavaConfigSample.class);
ConfigurationPropertiesSample configurationPropertiesSample=context.getBean(ConfigurationPropertiesSample.class);
DataSourceConfig dataSourceConfig=context.getBean(DataSourceConfig.class);
System.out.println("Application Demo. Input any key except quit to print the values. Input quit to exit.");
while (true) {
System.out.print("> ");
String input = new BufferedReader(new InputStreamReader(System.in, Charsets.UTF_8)).readLine();
if (!Strings.isNullOrEmpty(input) && input.trim().equalsIgnoreCase("quit")) {
System.exit(0);
}

if(javaConfigSample!=null){
System.out.println(javaConfigSample.toString());
}
if(configurationPropertiesSample!=null){
System.out.println(configurationPropertiesSample.toString());
}
if(dataSourceConfig!=null){
System.out.println(dataSourceConfig);
}

}
}
}


随便输入字符就可以显示监控的字段