依赖管理

  <!-- bootstrap最高级启动配置读取 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
<version>3.1.3</version>
</dependency> <!-- https://mvnrepository.com/artifact/com.ctrip.framework.apollo/apollo-client -->
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-openapi</artifactId>
<version>2.1.0</version>
</dependency>

application.properties

# Apollo
app.id=MORE-USER-USE
apollo.cache-dir=./ManyUser/apollo/cache
apollo.bootstrap.enabled=true
#apollo.bootstrap.namespaces=application.properties
apollo.meta=http://localhost:8080
apollo.bootstrap.eagerLoad.enabled=true
apollo.config-service=http://localhost:8080
env=DEV
apollo.use.admin.token=809d168da6f3baa39c02c1d376a0cc9cec852fa0fa8c6e2cff9b33e276d3738a
apollo.use.portal.url=http://localhost:8070

apollo-env.properties

dev.meta=http://localhost:8080

启动类 加入 @EnableApolloConfig

/**
* @description: 启动类
* @author: GuoTong
* @createTime: 2023-06-21 20:31
* @since JDK 1.8 OR 11
**/
@SpringBootApplication
@EnableApolloConfig
public class AppStartClass { public static void main(String[] args) {
SpringApplication.run(AppStartClass.class, args);
}
}

常规配置中心集成使用

package com.gton.user.config;

import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
import com.gton.user.io.Resp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import java.util.ArrayList;
import java.util.List; /**
* @description: Apollo同时还增加了几个新的Annotation来简化在Spring环境中的使用。
* @author: GuoTong
* @createTime: 2023-06-24 12:30
* @since JDK 1.8 OR 11
**/
@Component
@Slf4j
public class MyApolloConfig { /**
* ApolloJsonValue annotated on fields example, the default value is specified as empty list - []
* <br />
* jsonBeanProperty=[{"someString":"hello","someInt":100},{"someString":"world!","someInt":200}]
*/
@ApolloJsonValue("${jsonBeanProperty:[]}")
private List<Resp> anotherJsonBeans = new ArrayList<>(); @Value("${batch:100}")
private String batch; //config change listener for namespace application
@ApolloConfigChangeListener(value = "application")
private void apolloChange(ConfigChangeEvent changeEvent) {
//update injected value of batch if it is changed in Apollo
if (changeEvent.isChanged("batch")) {
batch = changeEvent.getChange("batch").getNewValue();
}
log.info(changeEvent.getNamespace() + "变化的key=>" + changeEvent.changedKeys() + ";==1");
} @ApolloConfigChangeListener(value = "order")
private void someOnChange(ConfigChangeEvent changeEvent) {
//update injected value of batch if it is changed in Apollo
if (changeEvent.isChanged("anotherJsonBeans")) {
log.info(changeEvent.getChange("anotherJsonBeans").getOldValue());
log.error(changeEvent.getChange("anotherJsonBeans").getNewValue());
}
log.info(anotherJsonBeans.toString());
log.info(changeEvent.getNamespace() + "变化的key=>" + changeEvent.changedKeys() + ";==1");
} }

Apollo 的开放平台使用

package com.gton.user.handler;

import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient;
import com.ctrip.framework.apollo.openapi.dto.NamespaceReleaseDTO;
import com.ctrip.framework.apollo.openapi.dto.OpenAppNamespaceDTO;
import com.ctrip.framework.apollo.openapi.dto.OpenItemDTO;
import com.ctrip.framework.apollo.openapi.dto.OpenPageDTO;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ClassPathResource; import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Properties; /**
* @description: Apollo开放平台操作
* @author: GuoTong
* @createTime: 2023-06-24 14:10
* @since JDK 1.8 OR 11
**/
public class ApolloOpenApiOperator { private ApolloOpenApiClient apolloOpenApiClient; private static ApolloOpenApiOperator apolloOpenApiOperator = null; public static ApolloOpenApiOperator getApolloOpenApiOperator() throws IOException { if (apolloOpenApiOperator == null) {
synchronized (ApolloOpenApiOperator.class) {
if (apolloOpenApiOperator == null) {
return new ApolloOpenApiOperator();
}
}
}
return apolloOpenApiOperator;
} public ApolloOpenApiOperator(ApolloOpenApiClient apolloOpenApiClient) {
this.apolloOpenApiClient = apolloOpenApiClient;
} public ApolloOpenApiOperator() throws IOException {
initApolloOpenApiOperator();
} private void initApolloOpenApiOperator() throws IOException {
// 获取配置文件
ClassPathResource classPathResource = new ClassPathResource("application.properties");
InputStream inputStream = classPathResource.getInputStream();
// 使用properties加载
Properties properties = new Properties();
properties.load(inputStream);
String token = properties.getProperty("apollo.use.admin.token");
String portalUrl = properties.getProperty("apollo.use.portal.url");
if (StringUtils.isNotEmpty(token)) {
this.apolloOpenApiClient = ApolloOpenApiClient
.newBuilder().
withConnectTimeout(60000).
withToken(token).
withPortalUrl(portalUrl).
withReadTimeout(60000)
.build();
} } public ApolloOpenApiClient getApolloOpenApiClient() {
return this.apolloOpenApiClient;
} /**
* Description: 创建NamSpace
*
* @param openAppNamespaceKey
* @author: GuoTong
* @date: 2023-06-24 15:04:44
* @return:void
*/
public void crateNameSpace(OpenAppNamespaceKey openAppNamespaceKey) { OpenAppNamespaceDTO openAppNamespaceDTO = new OpenAppNamespaceDTO();
openAppNamespaceDTO.setAppId(openAppNamespaceKey.getAppId());
openAppNamespaceDTO.setName(openAppNamespaceKey.getSpaceName());
openAppNamespaceDTO.setComment(openAppNamespaceKey.getSpaceDesc());
openAppNamespaceDTO.setPublic(openAppNamespaceKey.spaceIsPub);
apolloOpenApiClient.createAppNamespace(openAppNamespaceDTO);
} /**
* Description: 下发Apollo
*
* @param doIssueApolloKey
* @author: GuoTong
* @date: 2023-06-24 14:35:52
* @return:void
*/
public void doIssueApollo(DoIssueApolloKey doIssueApolloKey) {
OpenItemDTO openItemDTO = new OpenItemDTO();
openItemDTO.setKey(doIssueApolloKey.getKey());
openItemDTO.setValue(doIssueApolloKey.getValue());
openItemDTO.setComment(doIssueApolloKey.getDesc());
openItemDTO.setType(doIssueApolloKey.handlerValueType(doIssueApolloKey.getValueType()));
openItemDTO.setDataChangeCreatedBy(doIssueApolloKey.getOperator());
if (doIssueApolloKey.isModifiedOrInsert()) {
openItemDTO.setDataChangeLastModifiedBy(doIssueApolloKey.getOperator());
}
// 下发到Apollo
apolloOpenApiClient.createOrUpdateItem(
doIssueApolloKey.getAppId(),
doIssueApolloKey.getEnv(),
doIssueApolloKey.getClusterName(),
doIssueApolloKey.getNamespaceName(),
openItemDTO
); } /**
* Description: 发布整个NameSpace;推荐下发完成之后统一调一次,不要多次的下发操作,每一次下发都调用
*
* @param publishApolloKey
* @author: GuoTong
* @date: 2023-06-24 14:56:43
* @return:void
*/
public void executorPublish(PublishApolloKey publishApolloKey) { // apollo下发的数据执行发布
NamespaceReleaseDTO namespaceReleaseDTO = new NamespaceReleaseDTO();
//配置版本名称
namespaceReleaseDTO.setReleaseTitle(publishApolloKey.getReleaseTitle());
// 发布说明
namespaceReleaseDTO.setReleaseComment(publishApolloKey.getReleaseDescription());
// 操作员
namespaceReleaseDTO.setReleasedBy(publishApolloKey.getReleaseOperator());
apolloOpenApiClient.publishNamespace(publishApolloKey.getAppId(),
publishApolloKey.getEnv(),
publishApolloKey.getClusterName(),
publishApolloKey.getNamespaceName(), namespaceReleaseDTO); } /**
* Description: 移除Apollo的配置
* String appId, String env, String clusterName, String namespaceName, String key,
* String operator
*
* @param removeKeys
* @author: GuoTong
* @date: 2023-06-24 15:27:07
* @return:void
*/
public void executorRemove(DoIssueApolloKey removeKeys) {
apolloOpenApiClient.removeItem(removeKeys.getAppId(),
removeKeys.getEnv(),
removeKeys.getClusterName(),
removeKeys.getNamespaceName(), removeKeys.getKey(), removeKeys.getOperator());
} /**
* queryApolloKey many
*
* @param baseApolloKey
* @author: GuoTong
* @date: 2023-06-24 14:56:43
* @return:void
*/
public List<OpenItemDTO> queryApolloKey(BaseApolloKey baseApolloKey, int page, int size) { if (page <= 1) {
page = 0;
}
if (size <= 0) {
size = 10;
}
OpenPageDTO<OpenItemDTO> itemsByNamespace = apolloOpenApiClient.findItemsByNamespace(baseApolloKey.getAppId(),
baseApolloKey.getEnv(),
baseApolloKey.getClusterName(),
baseApolloKey.getNamespaceName(), page, size);
List<OpenItemDTO> content = itemsByNamespace.getContent();
return content; } /**
* queryApolloKey one
*
* @param baseApolloKey
* @author: GuoTong
* @date: 2023-06-24 14:56:43
* @return:void
*/
public OpenItemDTO queryApolloKeyOne(DoIssueApolloKey baseApolloKey) {
OpenItemDTO itemsByNamespace = apolloOpenApiClient.getItem(baseApolloKey.getAppId(),
baseApolloKey.getEnv(),
baseApolloKey.getClusterName(),
baseApolloKey.getNamespaceName(), baseApolloKey.getKey());
return itemsByNamespace; } @Data
public static class OpenAppNamespaceKey { private String appId; private String spaceName; private String spaceDesc; private boolean spaceIsPub = false; // 默认值 DEV
private String env = "DEV"; private String clusterName; private String namespaceName; } @Data
@NoArgsConstructor
@AllArgsConstructor
public static class DoIssueApolloKey extends BaseApolloKey { private String key; private String value; // 默认值 Apollo
private String operator = "Apollo"; private String desc; private String valueType; // 是否是修改
private boolean modifiedOrInsert; /**
* Description: 查询 Portal web的前端得出
*
* @author: GuoTong
* @date: 2023-06-24 14:46:42
* <select class="form-control ng-valid ng-valid-valdr ng-not-empty ng-dirty ng-touched ng-valid-parse" name="type" ng-model="item.type" ng-change="changeType()">
* <option value="0" class="ng-binding">String</option>
* <option value="1" class="ng-binding">Number</option>
* <option value="2" class="ng-binding">Boolean</option>
* <option value="3" class="ng-binding">JSON</option>
* </select>
*/
public int handlerValueType(String valueType) {
switch (valueType) {
case "String":
return 0;
case "Number":
return 1;
case "Boolean":
return 2;
case "JSON":
return 3; }
// 未匹配就默认使用String的值
return 0;
} } @Data
@NoArgsConstructor
@AllArgsConstructor
public static class BaseApolloKey { protected String appId; // 默认值 DEV
protected String env = "DEV"; // 默认值 default
protected String clusterName = "default"; protected String namespaceName; } @Data
public static class PublishApolloKey extends BaseApolloKey { // 发布时候的标题
private String releaseTitle; // 发布时候的操作员
private String releaseOperator; // 发布时候的DESC
private String releaseDescription; }
}

配合Controller使用

package com.gton.user.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ctrip.framework.apollo.openapi.dto.OpenItemDTO;
import com.gton.user.annotation.SwaggerScanClass;
import com.gton.user.handler.ApolloOpenApiOperator;
import com.gton.user.io.Resp;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import java.io.IOException;
import java.util.List;
import java.util.Map; /**
* 多租户表(apollo)表控制层
*
* @author 郭童
* @since 2023-06-22 16:28:10
*/
@RestController
@RequestMapping("apollo")
@SwaggerScanClass
public class ApolloOperatorController { /**
* 分页查询数据 namespaceName
*
* @param
* @return 所有数据
*/
@PostMapping("/queryLimit")
@ApiOperation("查询Apollo配置")
public Resp<List<OpenItemDTO>> queryPage(
@RequestParam("appId") String appId,
@RequestParam("clusterName") String clusterName,
@RequestParam("env") String env,
@RequestParam("namespaceName") String namespaceName
) throws IOException {
ApolloOpenApiOperator apolloOpenApiOperator = ApolloOpenApiOperator.getApolloOpenApiOperator();
ApolloOpenApiOperator.BaseApolloKey baseApolloKey = new ApolloOpenApiOperator.BaseApolloKey();
baseApolloKey.setAppId(appId);
baseApolloKey.setClusterName(clusterName);
baseApolloKey.setEnv(env);
baseApolloKey.setNamespaceName(namespaceName);
List<OpenItemDTO> openItemDTOS = apolloOpenApiOperator.queryApolloKey(baseApolloKey, 0, 10);
return Resp.Ok(openItemDTOS);
} /**
* 通过主键查询单条数据
*
* @param key apollo-key
* @return 单条数据
*/
@GetMapping("/queryOne/{key}")
public Resp<OpenItemDTO> selectOne(@PathVariable("key") String key,
@RequestParam("appId") String appId,
@RequestParam("clusterName") String clusterName,
@RequestParam("env") String env,
@RequestParam("namespaceName") String namespaceName) throws IOException {
ApolloOpenApiOperator apolloOpenApiOperator = ApolloOpenApiOperator.getApolloOpenApiOperator();
ApolloOpenApiOperator.DoIssueApolloKey baseApolloKey = new ApolloOpenApiOperator.DoIssueApolloKey();
baseApolloKey.setAppId(appId);
baseApolloKey.setEnv(env);
baseApolloKey.setNamespaceName(namespaceName);
baseApolloKey.setClusterName(clusterName);
baseApolloKey.setKey(key);
OpenItemDTO openItemDTO = apolloOpenApiOperator.queryApolloKeyOne(baseApolloKey);
return Resp.Ok(openItemDTO);
} /**
* 新增数据 到Apollo
*
* @param doIssueApolloKey 实体对象
* @return 新增结果
*/
@PostMapping("/save")
public Resp<String> insert(@RequestBody Map<String, String> doIssueApolloKey) throws IOException {
String json = JSON.toJSONString(doIssueApolloKey);
ApolloOpenApiOperator.DoIssueApolloKey doIssueApolloData = JSONObject.parseObject(json, ApolloOpenApiOperator.DoIssueApolloKey.class);
ApolloOpenApiOperator apolloOpenApiOperator = ApolloOpenApiOperator.getApolloOpenApiOperator();
doIssueApolloData.setModifiedOrInsert(false);
apolloOpenApiOperator.doIssueApollo(doIssueApolloData);
return Resp.Ok(doIssueApolloData.getKey());
} /**
* 修改数据
*
* @param doIssueApolloKey 实体对象
* @return 修改结果
*/
@PutMapping("/update")
public Resp<String> update(@RequestBody Map<String, String> doIssueApolloKey) throws IOException {
String json = JSON.toJSONString(doIssueApolloKey);
ApolloOpenApiOperator.DoIssueApolloKey doIssueApolloData = JSONObject.parseObject(json, ApolloOpenApiOperator.DoIssueApolloKey.class);
ApolloOpenApiOperator apolloOpenApiOperator = ApolloOpenApiOperator.getApolloOpenApiOperator();
doIssueApolloData.setModifiedOrInsert(true);
apolloOpenApiOperator.doIssueApollo(doIssueApolloData);
return Resp.Ok(doIssueApolloData.getKey());
} /**
* Description: 移出Apollo已下发数据
*
* @param key
* @param appId
* @param clusterName
* @param env
* @param namespaceName
* @author: GuoTong
* @date: 2023-06-24 15:42:24
* @return:com.gton.user.io.Resp<java.lang.String>
*/
@GetMapping("/dels")
public Resp<String> delete(@RequestParam("key") String key,
@RequestParam("appId") String appId,
@RequestParam("clusterName") String clusterName,
@RequestParam("env") String env,
@RequestParam("namespaceName") String namespaceName) throws IOException {
ApolloOpenApiOperator apolloOpenApiOperator = ApolloOpenApiOperator.getApolloOpenApiOperator();
ApolloOpenApiOperator.DoIssueApolloKey removeKeys = new ApolloOpenApiOperator.DoIssueApolloKey();
removeKeys.setAppId(appId);
removeKeys.setEnv(env);
removeKeys.setNamespaceName(namespaceName);
removeKeys.setClusterName(clusterName);
removeKeys.setKey(key);
apolloOpenApiOperator.executorRemove(removeKeys); return Resp.Ok(removeKeys.getKey());
}
}

Apollo2.1.0+Springboot使用OpenApI的更多相关文章

  1. solr8.0 springboot整合solr(四)

    引言: solr搭建起后,就该应用到java后台开发里了,接下来就用springboot整合应用solr 一:引入jar包 <!--solr--> <dependency> & ...

  2. 搭建 springboot 2.0 mybatis 读写分离 配置区分不同环境

    最近公司打算使用springboot2.0, springboot支持HTTP/2,所以提前先搭建一下环境.网上很多都在springboot1.5实现的,所以还是有些差异的.接下来咱们一块看一下. 文 ...

  3. Springboot 系列(十六)你真的了解 Swagger 文档吗?

    前言 目前来说,在 Java 领域使用 Springboot 构建微服务是比较流行的,在构建微服务时,我们大多数会选择暴漏一个 REST API 以供调用.又或者公司采用前后端分离的开发模式,让前端和 ...

  4. SpringBoot笔记一

    1 开始 1.1 spring介绍 Spring Boot使开发独立的,产品级别的基于Spring的应用变得非常简单,你只需"just run". 我们为Spring平台及第三方库 ...

  5. springboot 开发入门,及问题汇总

    1 . springboot简单介绍(http://projects.spring.io/spring-boot/) 现在的web项目几乎都会用到spring框架,而要使用spring难免需要配置大量 ...

  6. Spring Boot 2.0 教程 - 深入SpringAplication

    原文连接:https://www.codemore.top/cates/Backend/post/2018-05-20/spring-boot-SpringApplication 可以通过Spring ...

  7. 使用kbmmw 生成REST 服务OpenAPI函数原型

    我们以前介绍了很多kbmmw 开发REST 的例子.一直有个问题困惑着大家. 我们提供REST 服务,如何让客户端快速的使用,当然可以写文档,但是一旦 后台改变了,又要再一次给调用者发新文档,非常的麻 ...

  8. 初识elasticsearch_2(查询和整合springboot)

    初始化 首先将官网所下载的json文件,放入到es中,采用如下命令: curl -H "Content-Type: application/json" -XPOST 'localh ...

  9. springboot 整合 Redis 方法二

    方法一请参考之前博文 spring boot 整合 redis 自己的版本  java8 + redis3.0 + springboot 2.0.0 1 spring boot已经支持集成 redis ...

  10. OpenAPI初体验

    问题的一开始源于客户和服务部门抱怨我的REST API文档写得不好,然后又了解到 django rest framework 利用 coreapi 能自动生成文档,再就是看到 swagger.io 上 ...

随机推荐

  1. 浅谈 thinkphp composer 扩展包加载原理

    浅谈 thinkphp composer 扩展包加载原理 本文将介绍 ThinkPHP 中 Composer 扩展包的加载原理,帮助读者更好地理解和应用该功能. 前言 如题,今天感觉好久没有更新博客了 ...

  2. C++面试八股文:在C++中,有哪些可执行体?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第14面: 面试官:在C++中,有哪些可执行体? 二师兄:可执行体? 面试官:也就是可调用对象. 二师兄:让我想一想.函数.函数指针.类的静态方法.类 ...

  3. Pinot2的无人机传感器和摄像头

    目录 1. 引言 2. 技术原理及概念 2.1 基本概念解释 2.2 技术原理介绍 2.3 相关技术比较 无人机传感器和摄像头在Pinot 2中得到广泛应用,其目的是为Pinot 2提供全面的传感器和 ...

  4. kafka入门必备知识

    1. Kafka是一个分布式流处理平台: 可以让你发布和订阅流式的记录.这一方面与消息队列或者企业消息系统类似. 可以储存流式的记录,并且有较好的容错性. 可以在流式记录产生时就进行处理. 2. 消息 ...

  5. 移动端APP组件化架构实践

    前言 对于中大型移动端APP开发来讲,组件化是一种常用的项目架构方式.个人最近几年在工作项目中也一直使用组件化的方式来开发,在这过程中也积累了一些经验和思考.主要是来自在日常开发中使用组件化开发遇到的 ...

  6. CentOS 8搭建Docker镜像私有仓库-registry

    目录 简介 安装Docker 添加docker yum源 安装docker 确保网络模块开机自动加载 使桥接流量对iptables可见 配置docker 验证docker是否正常 添加用户到docke ...

  7. IIS部署的应用无法自动注册到Nacos

    问题描述: 自己开发的某系统后台API接入nacos,在IIS上部署无法自动注册到nacos服务列表中.其根本原因是网站处于休眠状态,当某请求访问该网站时,网站被激活,nacos注册成功. 但这块有个 ...

  8. PTA 21级数据结构与算法实验7—查找表

    目录 7-1 电话聊天狂人 7-2 两个有序序列的中位数 7-3 词频统计 7-4 集合相似度 7-5 悄悄关注 7-6 单身狗 7-7 词典 7-8 这是二叉搜索树吗? 7-9 二叉搜索树 7-1 ...

  9. 2023年郑州轻工业大学校赛邀请赛zxy

    第一次组队和大家去外校打比赛,真的是一次很棒的体验,尽管结果不尽人意,但总之收获颇丰,也认识到自身更多的不足. 本次比赛是三人一队,一台电脑,一分纸质试题,我们三人开始先从第一题开始,这题看起来还行, ...

  10. Windows安装SSH服务器

    1.打开Win的设置并在设置中找到应用 2.在应用中依次选择应用和功能 可选功能 3.在可选功能中选择添加功能 (OpenSSH客户端默认已存在) 选中OpenSSH服务器后点击下方的安装 4.快捷键 ...