携程Apollo(阿波罗)配置中心在Spring Boot项目快速集成
前提:先搭建好本地的单机运行项目:http://www.cnblogs.com/EasonJim/p/7643630.html
说明:下面的示例是基于Spring Boot搭建的,对于Spring项目基本通用。迁移旧项目的配置下一篇说明,这里先就如何快速的集成Client和获取配置的值进行实践。
0、下面的示例都是基于官方提供的教程去实践的,可以参考如下网址:
https://github.com/ctripcorp/apollo/wiki/Java%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97
https://github.com/ctripcorp/apollo/wiki/Apollo%E5%BC%80%E5%8F%91%E6%8C%87%E5%8D%97#23-java%E6%A0%B7%E4%BE%8B%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%90%AF%E5%8A%A8
1、先新建好Spring Boot项目,这里使用了Web做测试,所以引用了Thymeleaf模板。
搭建参考:http://www.cnblogs.com/EasonJim/p/7519854.html
2、登录Apollo上新建App和相关的配置项,可以参考如下配置:
3、在POM上引入Client的依赖,此时会有两个包引入Client和Core。
<dependency><groupId>com.ctrip.framework.apollo</groupId><artifactId>apollo-client</artifactId><version>0.8.0</version></dependency>
4、在项目上配置上面设置的app.id,注意此时是通过新建META-INF/app.properties文件实现的。
5、代码实现
实现的功能是通过配置中心修改后,再次刷新页面而不重启应用的情况下能看到值的改变。
实现方式主要几种在两种,1为通过API的形式增加监听回调函数来监听值的改变后直接修改,2为通过注入Bean的方式使用Bean下的专用监听注解实现回调监听。
5.1、通过API的方式
代码实现如下:
package com.jsoft.springboottest.springboottest1.controller;import org.slf4j.Logger; import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod;import com.ctrip.framework.apollo.Config; import com.ctrip.framework.apollo.ConfigChangeListener; import com.ctrip.framework.apollo.ConfigService; import com.ctrip.framework.apollo.model.ConfigChange; import com.ctrip.framework.apollo.model.ConfigChangeEvent; import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;@Controller public class IndexController {private static final Logger logger = LoggerFactory.getLogger(IndexController.class);private Config config;private int timeout;private int batch;private String url;@RequestMapping(value = "/index", method = RequestMethod.GET)public String index(Model model) {Entry entry = new Entry();entry.setText("Text");entry.setTitle("Title");model.addAttribute("entries", entry);model.addAttribute("entry", new Entry());model.addAttribute("url", url);model.addAttribute("timeout",timeout);model.addAttribute("batch",batch);logger.info("timeout:{}", timeout);logger.info("batch:{}", batch);logger.info("url:{}", url);return "index";}public IndexController() {config = ConfigService.getAppConfig();config.addChangeListener(new ConfigChangeListener() {@Overridepublic void onChange(ConfigChangeEvent changeEvent) {logger.info("Changes for namespace {}", changeEvent.getNamespace());for (String key : changeEvent.changedKeys()) {ConfigChange change = changeEvent.getChange(key);logger.info("Change - key: {}, oldValue: {}, newValue: {}, changeType: {}", change.getPropertyName(), change.getOldValue(), change.getNewValue(), change.getChangeType());if (key.equals("url")) {url = change.getNewValue();}if(key.equals("batch")) {batch = Integer.valueOf(change.getNewValue());}if (key.equals("timeout")) {timeout = Integer.valueOf(change.getNewValue());}} }});}}
说明:
通过新建Config对象,使用的是ConfigService.getAppConfig()获取默认配置,也就是配置中心中的application.properties的,当然,getAppConfig可以指定不能的namespage。
通过获取Config对象增加监听回调函数addChangeListener。监听指定的值变化后,重新赋值变量。
这种方式应该是最简单的,不用写特殊的注解去实现,但是可能在运行时也会发现,程序在一启动时不会去获取默认的配置值,比如timeout这些是空的,要解决这个问题时需要在Class上增加@EnableApolloConfig的注解,然后在属性上增加@Value的值即可,改动如下:
package com.jsoft.springboottest.springboottest1.controller;import org.slf4j.Logger; import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod;import com.ctrip.framework.apollo.Config; import com.ctrip.framework.apollo.ConfigChangeListener; import com.ctrip.framework.apollo.ConfigService; import com.ctrip.framework.apollo.model.ConfigChange; import com.ctrip.framework.apollo.model.ConfigChangeEvent; import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;@Controller @EnableApolloConfig public class IndexController {private static final Logger logger = LoggerFactory.getLogger(IndexController.class);private Config config;@Value("${timeout:200}")private int timeout; @Value("${batch:200}")private int batch;@Value("${url:http://easonjim.com}")private String url;@RequestMapping(value = "/index", method = RequestMethod.GET)public String index(Model model) {Entry entry = new Entry();entry.setText("Text");entry.setTitle("Title");model.addAttribute("entries", entry);model.addAttribute("entry", new Entry());model.addAttribute("url", url);model.addAttribute("timeout",timeout);model.addAttribute("batch",batch);logger.info("timeout:{}", timeout);logger.info("batch:{}", batch);logger.info("url:{}", url);return "index";}public IndexController() {config = ConfigService.getAppConfig();config.addChangeListener(new ConfigChangeListener() {@Overridepublic void onChange(ConfigChangeEvent changeEvent) {logger.info("Changes for namespace {}", changeEvent.getNamespace());for (String key : changeEvent.changedKeys()) {ConfigChange change = changeEvent.getChange(key);logger.info("Change - key: {}, oldValue: {}, newValue: {}, changeType: {}", change.getPropertyName(), change.getOldValue(), change.getNewValue(), change.getChangeType());if (key.equals("url")) {url = change.getNewValue();}if(key.equals("batch")) {batch = Integer.valueOf(change.getNewValue());}if (key.equals("timeout")) {timeout = Integer.valueOf(change.getNewValue());}} }});}}
说明:约定俗成,在@Value上获取值时记得增加默认值,以防止获取为空。
上面代码或许有些冗余,可以再提炼一下,因为config对象的值会实时更新,所以也不需要监听onChange事件,也不需要自己创建一个变量,最后代码实现如下:
package com.jsoft.springboottest.springboottest1.controller;import org.slf4j.Logger; import org.slf4j.LoggerFactory;import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod;import com.ctrip.framework.apollo.Config; import com.ctrip.framework.apollo.ConfigChangeListener; import com.ctrip.framework.apollo.ConfigService; import com.ctrip.framework.apollo.model.ConfigChange; import com.ctrip.framework.apollo.model.ConfigChangeEvent; import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;@Controller public class IndexController2 {private static final Logger logger = LoggerFactory.getLogger(IndexController2.class);private Config config = ConfigService.getAppConfig();@RequestMapping(value = "/index2", method = RequestMethod.GET)public String index(Model model) {Entry entry = new Entry();entry.setText("Text");entry.setTitle("Title");model.addAttribute("entries", entry);model.addAttribute("entry", new Entry());model.addAttribute("url", config.getProperty("url", ""));model.addAttribute("timeout",config.getProperty("timeout", ""));model.addAttribute("batch",config.getProperty("batch", ""));logger.info("timeout:{}", config.getProperty("timeout", ""));logger.info("batch:{}", config.getProperty("batch", ""));logger.info("url:{}", config.getProperty("url", ""));return "index";}}
5.2、通过注入Bean的方式
5.2.1、新建的Bean如下:
package com.jsoft.springboottest.springboottest1.controller;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 org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value;import javax.annotation.PostConstruct;public class AnnotatedBean {private static final Logger logger = LoggerFactory.getLogger(AnnotatedBean.class);@Value("${timeout:200}")private int timeout;private int batch;@ApolloConfigprivate Config config;@ApolloConfig("FX.apollo")private Config anotherConfig;@PostConstructvoid initialize() {logger.info("timeout is {}", timeout);logger.info("batch is {}", batch);logger.info("Keys for config: {}", config.getPropertyNames());logger.info("Keys for anotherConfig: {}", anotherConfig.getPropertyNames());}@Value("${batch:100}")public void setBatch(int batch) {this.batch = batch;}public int getBatch() {return batch;}public int getTimeout() {return timeout;}@ApolloConfigChangeListener("application")private void someChangeHandler(ConfigChangeEvent changeEvent) {logger.info("[someChangeHandler]Changes for namespace {}", changeEvent.getNamespace());if (changeEvent.isChanged("timeout")) {refreshTimeout();}if (changeEvent.isChanged("batch")) {setBatch(Integer.valueOf(changeEvent.getChange("batch").getNewValue()));}}@ApolloConfigChangeListener({ "application", "FX.apollo" })private void anotherChangeHandler(ConfigChangeEvent changeEvent) {logger.info("[anotherChangeHandler]Changes for namespace {}", changeEvent.getNamespace());for (String key : changeEvent.changedKeys()) {ConfigChange change = changeEvent.getChange(key);logger.info("[anotherChangeHandler]Change - key: {}, oldValue: {}, newValue: {}, changeType: {}", change.getPropertyName(), change.getOldValue(), change.getNewValue(), change.getChangeType());}}private void refreshTimeout() {// do some custom logic to update placeholder valuetimeout = config.getIntProperty("timeout", timeout);logger.info("Refreshing timeout to {}", timeout);} }
5.2.2、通过@Configuration注入这个Bean,代码如下:
package com.jsoft.springboottest.springboottest1.controller;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;@Configuration @EnableApolloConfig public class AnnotatedConfig {@Beanpublic AnnotatedBean annotatedBean() {return new AnnotatedBean();} }
注意:要增加@EnableApolloConfig和@Configuration,不然不会生效。并且留意到@Bean的注解,如果没有这个时,@ApolloConfigChangeListener不会生效。这个是关键所在,@ApolloConfigChangeListener只能用于Bean注入上,这个和API的方式有明显区别。
在代码上使用:
package com.jsoft.springboottest.springboottest1.controller;import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;@RestController public class TestController {private static final Logger logger = LoggerFactory.getLogger(TestController.class);@Autowiredprivate AnnotatedBean annotatedBean;@RequestMapping("/show")public String show(){logger.info("batch:{}",annotatedBean.getBatch());logger.info("timeout:{}",annotatedBean.getTimeout());return "Hello World"+" batch:"+annotatedBean.getBatch()+" timeout:"+annotatedBean.getTimeout(); } }
说明:可以看出,只要@Autowired注入刚才的Bean就可以直接使用。
6、运行,一般只需要在/opt/settings/server.properties中配置了env=DEV就可以直接直接启动(因为Client在本地仓库的包上已经有了meta_server的信息),但是在IDE上也可以通过指定VM的参数,增加系统属性变量-D来实现调试,配置如下:
如果到处JAR运行,直接java -jar Spring-Boot-Demo.jar即可,不需要增加什么参数(但前提是配置了/opt/settings/server.properties的env的值)。
测试代码:https://github.com/easonjim/5_java_example/tree/master/apollotest/test1
转载于:https://www.cnblogs.com/EasonJim/p/7649047.html
携程Apollo(阿波罗)配置中心在Spring Boot项目快速集成相关推荐
- 携程Apollo(阿波罗)配置中心在.NET Core项目快速集成
.NET Core的支持文档大体上可以参考文档.Net客户端使用指南:https://github.com/ctripcorp/apollo/wiki/.Net%E5%AE%A2%E6%88%B7%E ...
- Apollo - 阿波罗配置中心使用,一文搞定!
Apollo基本概念 一.简介 Apollo - A reliable configuration management system Apollo的Github地址 Apollo(阿波罗)是携程框架 ...
- Apollo阿波罗配置中心基本概述
1.什么是Apollo: Apollo(阿波罗)是一款可靠的分布式配置管理中心,诞生于携程框架研发部,能够集中化管理应用不同环境.不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限.流 ...
- apollo配置中心之--spring boot如何加载apollo
文章目录 一.启动类上加入@EnableApollo注解 1.1.PropertySourcesProcessor#initializePropertySources()从apollo服务端拉取配置封 ...
- IDEA 2020 配置 Maven 创建 Spring Boot 项目
文章目录 Maven 安装配置 Maven 配置 Maven 仓库(仓库路径.阿里云下载) IDEA 配置 Maven IDEA 创建 springboot 项目 在新电脑上配环境总是要不停的百度,简 ...
- linux阿波罗配置文件放在哪,Apollo阿波罗配置中心
一.准备工作 1.2.1 AppId classpath:/META-INF/app.properties 内容app.id=YOUR-APP-ID 1.2.2 Environment 对于Mac/ ...
- Apollo阿波罗配置中心
一.准备工作 1.2.1 AppId classpath:/META-INF/app.properties 内容app.id=YOUR-APP-ID 1.2.2 Environment 对于Mac/ ...
- SpringCloud - Spring Cloud 之 Apollo Config携程阿波罗配置中心(二十一)
由于Spring Cloud自带的Config 需要配合 Bus 使用,且不能实时刷新,因此市面上出现了很多开元的配置中心 市面上开源的配置中心 Apollo(阿波罗):携程框架部门研发的分布式配置中 ...
- 携程Apollo分布式配置中心搭建指南
Apollo配置中心介绍 Apollo(阿波罗)是携程框架部门研发的开源配置管理中心,能够集中化管理应用不同环境.不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限.流程治理等特性. ...
最新文章
- 寻找正反物质世界边境的长城---兵粒子
- Kerberos协议
- 【插件】史上最强编辑器通用ctags插件OpenCTags使用指南v1.2--开发者必备
- Mongodb查询分析器解析
- Tokenizers: How machines read
- Android Multimedia框架总结(二)MediaPlayer框架及播放网络视频案例
- cv2 python 读取像素点_OpenCV+Python车牌字符分割和识别入门
- python英语单词库app_英语单词库【英语单词库英语头条】- 英语单词库知识点 - 中企动力...
- Java中的增强for
- node.js、React和VUE的纯理论
- Hexo更换主题教程
- 开发者的如何优雅的使用OSX
- 股票自动委托下单html,股票怎么设置自动挂单?股票交易挂单规则
- textarea输入框实时 统计字数(可统计中文,英文字数)
- DOS命令:systeminfo
- 10分钟认识低代码平台
- 错误: 对象不支持“attachEvent”属性或方法
- Python数据可视化图表大全
- OneNote的正确登出方式
- 根据日期获取生肖,根据日期获取星座
热门文章
- 【测试工具】工具整理
- [安卓] 18、一个简单的例子做自定义动画按钮和自定义Actionbar
- Windows 8实例教程系列 - 开篇
- Discuz!NT 模板机制分析
- vue-cli入门(四)——vue-resource登录注册实例
- Spring源码学习笔记:经典设计模式之装饰者模式
- L1-066 猫是液体 (5 分)-PAT 团体程序设计天梯赛 GPLT
- 蓝桥杯 ADV-63 算法提高 利息计算
- 蓝桥杯 BEGIN-1 入门训练 A+B问题
- windows优化大师怎么用_软件不能用又卸载不掉怎么办——用Windows自家的卸载工具吧(dos级卸载)...