diff --git a/dev-protocol-springcloud/dev-protocol-springcloud-gateway/README-SpringCloud-Gateway.md b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/README-SpringCloud-Gateway.md
new file mode 100644
index 0000000..340135d
--- /dev/null
+++ b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/README-SpringCloud-Gateway.md
@@ -0,0 +1,41 @@
+# SpringCloud - Gateway
+
+
+## 1. 基础介绍
+
+- SpringCloud Gateway 的核心概念
+ - SpringCloud Gateway 是 Spring 官方最新推出的一款基于 SpringFramework 5, Project Reactor 和SpringBoot 2之上开发的网关
+ - 它与第一代网关 Zuu 不同的是: gateway 是异步非阻塞的(netty + webflux 实现), zuul是同步阻塞请求的
+ - Gateway 三大组成部分
+ - Route 路由(ID + 目标URL) - Predicate 断言 - Filter 过滤器
+
+
+- SpringCloud Gateway 的工作模型
+ - SpringCloud Gateway 工作模型图示及解读
+ - 请求发送到网关,经由分发器将请求匹配到相应的 HandlerMapping
+ - 请求和处理器之间有一个映射,路由到网关处理程序,即 Web Handler
+ - 执行特定的请求过滤器链 (Filters Proxy Filter)
+ - 最终到达代理的微服务 (Proxied Service)
+---
+## 2. 谓词 Predicate 的原理与应用
+
+- 参考: [PredicateTest.java]
+
+## 3. 集成 Nacos 实现动态路由配置
+
+- 静态路由配置
+ - 静态路由配置写在配置文件中(yml或者 properties 文件中),端点是:spring.cloud.gateway
+ - 缺点非常明显,每次改动都需要网关模块重新部署
+---
+## 4. 注册网关事件监听器
+
+- 参考: [DynamicRouteServiceImpl.java] | [DynamicRouteServiceImplByNacos.java]
+
+- 验证网关监听器的可用性 修改看是否可以生效, 已经测试成功
+
+---
+## 5. 解读 SpringCloud Gateway Filter
+
+
+
+
diff --git a/dev-protocol-springcloud/dev-protocol-springcloud-gateway/README.md b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/README.md
deleted file mode 100644
index a2bff58..0000000
--- a/dev-protocol-springcloud/dev-protocol-springcloud-gateway/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# SpringCloud - Gateway
-
-- 对 SpringCloud - Gateway 进行研究
diff --git a/dev-protocol-springcloud/dev-protocol-springcloud-gateway/pom.xml b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/pom.xml
index 12cfa97..c9360ad 100644
--- a/dev-protocol-springcloud/dev-protocol-springcloud-gateway/pom.xml
+++ b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/pom.xml
@@ -11,6 +11,8 @@
dev-protocol-springcloud-gateway
+ 1.0-SNAPSHOT
+ jar
8
@@ -18,4 +20,74 @@
UTF-8
+
+ e-commerce-gateway
+ Spring Cloud Gateway
+
+
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+
+
+
+ com.alibaba.cloud
+ spring-cloud-starter-alibaba-nacos-discovery
+
+
+ org.springframework.cloud
+ spring-cloud-starter-gateway
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ com.alibaba
+ fastjson
+ 1.2.51
+
+
+
+
+
+ ${artifactId}
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/java/org/example/GatewayApplication.java b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/java/org/example/GatewayApplication.java
new file mode 100644
index 0000000..02c93e2
--- /dev/null
+++ b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/java/org/example/GatewayApplication.java
@@ -0,0 +1,17 @@
+package org.example;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+
+/**
+ *
网关启动入口
+ * */
+@EnableDiscoveryClient
+@SpringBootApplication
+public class GatewayApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(GatewayApplication.class, args);
+ }
+}
\ No newline at end of file
diff --git a/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/java/org/example/Main.java b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/java/org/example/Main.java
deleted file mode 100644
index 407f157..0000000
--- a/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/java/org/example/Main.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package org.example;
-
-public class Main {
- public static void main(String[] args) {
- System.out.println("Hello world!");
- }
-}
\ No newline at end of file
diff --git a/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/java/org/example/conf/DynamicRouteServiceImpl.java b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/java/org/example/conf/DynamicRouteServiceImpl.java
new file mode 100644
index 0000000..6768246
--- /dev/null
+++ b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/java/org/example/conf/DynamicRouteServiceImpl.java
@@ -0,0 +1,122 @@
+package org.example.conf;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.gateway.event.RefreshRoutesEvent;
+import org.springframework.cloud.gateway.route.RouteDefinition;
+import org.springframework.cloud.gateway.route.RouteDefinitionLocator;
+import org.springframework.cloud.gateway.route.RouteDefinitionWriter;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.context.ApplicationEventPublisherAware;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import reactor.core.publisher.Mono;
+
+import java.util.List;
+
+/**
+ * 事件推送 Aware: 动态更新路由网关 Service
+ *
+ * 实现 ApplicationEventPublisherAware 事件推送接口
+ * */
+@Slf4j
+@Service
+@SuppressWarnings("all")
+public class DynamicRouteServiceImpl implements ApplicationEventPublisherAware {
+
+ /** 写路由定义 */
+ private final RouteDefinitionWriter routeDefinitionWriter;
+ /** 获取路由定义 */
+ private final RouteDefinitionLocator routeDefinitionLocator;
+
+ /** 事件发布 */
+ private ApplicationEventPublisher publisher;
+
+ public DynamicRouteServiceImpl(RouteDefinitionWriter routeDefinitionWriter,
+ RouteDefinitionLocator routeDefinitionLocator) {
+ this.routeDefinitionWriter = routeDefinitionWriter;
+ this.routeDefinitionLocator = routeDefinitionLocator;
+ }
+
+ @Override
+ public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
+ // 完成事件推送句柄的初始化
+ this.publisher = applicationEventPublisher;
+ }
+
+ /**
+ * 增加路由定义
+ * */
+ public String addRouteDefinition(RouteDefinition definition) {
+
+ log.info("gateway add route: [{}]", definition);
+
+ // 保存路由配置并发布
+ routeDefinitionWriter.save(Mono.just(definition)).subscribe();
+ // 发布事件通知给 Gateway, 同步新增的路由定义
+ this.publisher.publishEvent(new RefreshRoutesEvent(this));
+
+ return "success";
+ }
+
+ /**
+ * 更新路由
+ * */
+ public String updateList(List definitions) {
+
+ log.info("gateway update route: [{}]", definitions);
+
+ // 先拿到当前 Gateway 中存储的路由定义
+ List routeDefinitionsExits =
+ routeDefinitionLocator.getRouteDefinitions().buffer().blockFirst();
+ if (!CollectionUtils.isEmpty(routeDefinitionsExits)) {
+ // 清除掉之前所有的 "旧的" 路由定义
+ routeDefinitionsExits.forEach(rd -> {
+ log.info("delete route definition: [{}]", rd);
+ deleteById(rd.getId());
+ });
+ }
+
+ // 把更新的路由定义同步到 gateway 中
+ definitions.forEach(definition -> updateByRouteDefinition(definition));
+ return "success";
+ }
+
+ /**
+ * 根据路由 id 删除路由配置
+ * */
+ private String deleteById(String id) {
+
+ try {
+ log.info("gateway delete route id: [{}]", id);
+ this.routeDefinitionWriter.delete(Mono.just(id)).subscribe();
+ // 发布事件通知给 gateway 更新路由定义
+ this.publisher.publishEvent(new RefreshRoutesEvent(this));
+ return "delete success";
+ } catch (Exception ex) {
+ log.error("gateway delete route fail: [{}]", ex.getMessage(), ex);
+ return "delete fail";
+ }
+ }
+
+ /**
+ * 更新路由
+ * 更新的实现策略比较简单: 删除 + 新增 = 更新
+ * */
+ private String updateByRouteDefinition(RouteDefinition definition) {
+
+ try {
+ log.info("gateway update route: [{}]", definition);
+ this.routeDefinitionWriter.delete(Mono.just(definition.getId()));
+ } catch (Exception ex) {
+ return "update fail, not find route routeId: " + definition.getId();
+ }
+
+ try {
+ this.routeDefinitionWriter.save(Mono.just(definition)).subscribe();
+ this.publisher.publishEvent(new RefreshRoutesEvent(this));
+ return "success";
+ } catch (Exception ex) {
+ return "update route fail";
+ }
+ }
+}
diff --git a/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/java/org/example/conf/DynamicRouteServiceImplByNacos.java b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/java/org/example/conf/DynamicRouteServiceImplByNacos.java
new file mode 100644
index 0000000..0f891e7
--- /dev/null
+++ b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/java/org/example/conf/DynamicRouteServiceImplByNacos.java
@@ -0,0 +1,127 @@
+package org.example.conf;
+
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.nacos.api.NacosFactory;
+import com.alibaba.nacos.api.config.ConfigService;
+import com.alibaba.nacos.api.exception.NacosException;
+import com.alibaba.nacos.api.config.listener.Listener;
+import com.alibaba.nacos.common.utils.CollectionUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.cloud.gateway.route.RouteDefinition;
+import org.springframework.context.annotation.DependsOn;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import java.util.concurrent.Executor;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * 通过 nacos 下发动态路由配置, 监听 Nacos 中路由配置变更
+ * */
+@Slf4j
+@Component
+@DependsOn({"gatewayConfig"}) // 依赖于 GatewayConfig 这个 Bean , 注意要首字母小写
+public class DynamicRouteServiceImplByNacos {
+ /** Nacos 配置服务 */
+ private ConfigService configService;
+ private final DynamicRouteServiceImpl dynamicRouteService;
+
+ public DynamicRouteServiceImplByNacos(DynamicRouteServiceImpl dynamicRouteService) {
+ this.dynamicRouteService = dynamicRouteService;
+ }
+
+ /**
+ * Bean 在容器中构造完成之后会执行 init 方法
+ * */
+ @PostConstruct
+ public void init() {
+
+ log.info("gateway route init....");
+
+ try {
+ // 初始化 Nacos 配置客户端
+ configService = initConfigService();
+ if (null == configService) {
+ log.error("init config service fail");
+ return;
+ }
+
+ // 通过 Nacos Config 并指定路由配置路径去获取路由配置
+ String configInfo = configService.getConfig(
+ GatewayConfig.NACOS_ROUTE_DATA_ID,
+ GatewayConfig.NACOS_ROUTE_GROUP,
+ GatewayConfig.DEFAULT_TIMEOUT
+ );
+
+ log.info("get current gateway config: [{}]", configInfo);
+ List definitionList = JSON.parseArray(configInfo, RouteDefinition.class);
+
+ if (CollectionUtils.isNotEmpty(definitionList)) {
+ for (RouteDefinition definition : definitionList) {
+ log.info("init gateway config: [{}]", definition.toString());
+ dynamicRouteService.addRouteDefinition(definition);
+ }
+ }
+
+ } catch (Exception ex) {
+ log.error("gateway route init has some error: [{}]", ex.getMessage(), ex);
+ }
+
+ // 设置监听器
+ dynamicRouteByNacosListener(GatewayConfig.NACOS_ROUTE_DATA_ID, GatewayConfig.NACOS_ROUTE_GROUP);
+ }
+
+ /**
+ * 初始化 Nacos Config
+ * */
+ private ConfigService initConfigService() {
+
+ try {
+ Properties properties = new Properties();
+ properties.setProperty("serverAddr", GatewayConfig.NACOS_SERVER_ADDR);
+ properties.setProperty("namespace", GatewayConfig.NACOS_NAMESPACE);
+ return configService = NacosFactory.createConfigService(properties);
+ } catch (Exception ex) {
+ log.error("init gateway nacos config error: [{}]", ex.getMessage(), ex);
+ return null;
+ }
+ }
+
+ /**
+ * 监听 Nacos 下发的动态路由配置
+ * */
+ private void dynamicRouteByNacosListener(String dataId, String group) {
+
+ try {
+ // 给 Nacos Config 客户端增加一个监听器
+ configService.addListener(dataId, group, new Listener() {
+
+ /**
+ * 自己提供线程池执行操作
+ * */
+ @Override
+ public Executor getExecutor() {
+ // 通常不需要自己提供用默认提供的即可
+ return null;
+ }
+
+ /**
+ * 监听器收到配置更新
+ * @param configInfo Nacos 中最新的配置定义
+ * */
+ @Override
+ public void receiveConfigInfo(String configInfo) {
+
+ log.info("start to update config: [{}]", configInfo);
+ List definitionList = JSON.parseArray(configInfo, RouteDefinition.class);
+ log.info("update route: [{}]", definitionList.toString());
+ dynamicRouteService.updateList(definitionList);
+ }
+ });
+ } catch (NacosException ex) {
+ log.error("dynamic update gateway config error: [{}]", ex.getMessage(), ex);
+ }
+ }
+}
diff --git a/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/java/org/example/conf/GatewayConfig.java b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/java/org/example/conf/GatewayConfig.java
new file mode 100644
index 0000000..0f347f6
--- /dev/null
+++ b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/java/org/example/conf/GatewayConfig.java
@@ -0,0 +1,46 @@
+package org.example.conf;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 配置类, 读取 Nacos 相关的配置项, 用于配置监听器
+ * */
+@Configuration
+public class GatewayConfig {
+
+ /** 读取配置的超时时间 */
+ public static final long DEFAULT_TIMEOUT = 30000;
+
+ /** Nacos 服务器地址 */
+ public static String NACOS_SERVER_ADDR;
+
+ /** 命名空间 */
+ public static String NACOS_NAMESPACE;
+
+ /** data-id */
+ public static String NACOS_ROUTE_DATA_ID;
+
+ /** 分组 id */
+ public static String NACOS_ROUTE_GROUP;
+
+ @Value("${spring.cloud.nacos.discovery.server-addr}")
+ public void setNacosServerAddr(String nacosServerAddr) {
+ NACOS_SERVER_ADDR = nacosServerAddr;
+ }
+
+ @Value("${spring.cloud.nacos.discovery.namespace}")
+ public void setNacosNamespace(String nacosNamespace) {
+ NACOS_NAMESPACE = nacosNamespace;
+ }
+
+ @Value("${nacos.gateway.route.config.data-id}")
+ public void setNacosRouteDataId(String nacosRouteDataId) {
+ NACOS_ROUTE_DATA_ID = nacosRouteDataId;
+ }
+
+ @Value("${nacos.gateway.route.config.group}")
+ public void setNacosRouteGroup(String nacosRouteGroup) {
+ NACOS_ROUTE_GROUP = nacosRouteGroup;
+ }
+}
diff --git a/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/resources/bootstrap.yml b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/resources/bootstrap.yml
new file mode 100644
index 0000000..fe928cb
--- /dev/null
+++ b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/resources/bootstrap.yml
@@ -0,0 +1,54 @@
+server:
+ port: 9001
+ servlet:
+ context-path: /dev-protocol-springcloud-gateway
+
+spring:
+ application:
+ name: dev-protocol-springcloud-gateway
+ cloud:
+ nacos:
+ discovery:
+ enabled: true # 如果不想使用 Nacos 进行服务注册和发现, 设置为 false 即可
+ server-addr: 127.0.0.1:8848 # Nacos 服务器地址
+ namespace: 1ccc74ae-9398-4dbe-b9d7-4f9addf9f40c
+ metadata:
+ management:
+ context-path: ${server.servlet.context-path}/actuator
+ # 静态路由
+ # gateway:
+ # routes:
+ # - id: path_route # 路由的ID
+ # uri: 127.0.0.1:8080/user/{id} # 匹配后路由地址
+ # predicates: # 断言, 路径相匹配的进行路由
+ # - Path=/user/{id}
+# kafka:
+# bootstrap-servers: 127.0.0.1:9092
+# producer:
+# retries: 3
+# consumer:
+# auto-offset-reset: latest
+# zipkin:
+# sender:
+# type: kafka # 默认是 web
+# base-url: http://localhost:9411/
+ main:
+ allow-bean-definition-overriding: true # 因为将来会引入很多依赖, 难免有重名的 bean
+
+# 这个地方独立配置, 是网关的数据, 代码 GatewayConfig.java 中读取被监听
+nacos:
+ gateway:
+ route:
+ config:
+ data-id: dev-protocol-springcloud-gateway-router
+ group: dev-protocol
+
+# 暴露端点
+management:
+ endpoints:
+ web:
+ exposure:
+ include: '*'
+ endpoint:
+ health:
+ show-details: always
diff --git a/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/resources/http/login.http b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/resources/http/login.http
new file mode 100644
index 0000000..25e22f1
--- /dev/null
+++ b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/resources/http/login.http
@@ -0,0 +1,17 @@
+### 登录
+POST 127.0.0.1:9001/imooc/e-commerce/login
+Content-Type: application/json
+
+{
+ "username": "Qinyi@imooc.com",
+ "password": "25d55ad283aa400af464c76d713c07ad"
+}
+
+###
+POST 127.0.0.1:9001/imooc/e-commerce/register
+Content-Type: application/json
+
+{
+ "username": "ImoocQinyi@imooc.com",
+ "password": "25d55ad283aa400af464c76d713c07ad"
+}
diff --git a/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/resources/http/nacos-client.http b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/resources/http/nacos-client.http
new file mode 100644
index 0000000..a0a713c
--- /dev/null
+++ b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/main/resources/http/nacos-client.http
@@ -0,0 +1,5 @@
+### 查询服务
+GET http://127.0.0.1:9001/imooc/ecommerce-nacos-client/nacos-client/service-instance?serviceId=e-commerce-gateway
+Accept: application/json
+e-commerce-user: eyJhbGciOiJSUzI1NiJ9.eyJlLWNvbW1lcmNlLXVzZXIiOiJ7XCJpZFwiOjE3LFwidXNlcm5hbWVcIjpcIkltb29jUWlueWlAaW1vb2MuY29tXCJ9IiwianRpIjoiMGIxNzQyYWItMWU3OC00OTZjLWIyNTAtMjNkZGQ1ZGEyZTU1IiwiZXhwIjoxNjI0MjA0ODAwfQ.QKGHzohSHdYDHzUVHpe9gNPUgzfkPwrSbB-WiMWYjLlt2tr9BufzZM8bSt-whb_bd0hKoC6rkYYO0WUVR67uSML-2yaTL1xMIn8GH9Flyig3rpO4vefL3Hp2TXIpwHHa7WlKsLzcUpNk9lxWs2B5k0ICdYCH_jD5Tx6N7CzfSUG9u4fOnVeM9UFE2nX_DURupUh_DKCc2oOoMeyCSR7Ma8-Ab4WQU3r-U0YivR8G1A0kmKOIoTeRhM3LcPuxUPh3rCbrjzMg--fexRGw0O38Qsby6pz-ku2IlTyFXY6_jNOG1BZR34-jBOnaIciP1TExw9bFumeuC2GcowTHJVH1Nw
+token: imooc
diff --git a/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/test/java/org/example/GatewayApplicationTest.java b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/test/java/org/example/GatewayApplicationTest.java
new file mode 100644
index 0000000..5ed8a8e
--- /dev/null
+++ b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/test/java/org/example/GatewayApplicationTest.java
@@ -0,0 +1,18 @@
+package org.example;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+/**
+ * 验证工程搭建的正确性测试用例
+ * */
+@SpringBootTest
+@RunWith(SpringRunner.class)
+public class GatewayApplicationTest {
+
+ @Test
+ public void contextLoad() {
+
+ }
+}
diff --git a/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/test/java/org/example/service/PredicateTest.java b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/test/java/org/example/service/PredicateTest.java
new file mode 100644
index 0000000..f53b38f
--- /dev/null
+++ b/dev-protocol-springcloud/dev-protocol-springcloud-gateway/src/test/java/org/example/service/PredicateTest.java
@@ -0,0 +1,83 @@
+package org.example.service;
+
+import lombok.extern.slf4j.Slf4j;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Predicate;
+
+/**
+ * Java8 Predicate 使用方法与思想
+ * */
+@Slf4j
+@SpringBootTest
+@RunWith(SpringRunner.class)
+public class PredicateTest {
+
+ public static List MICRO_SERVICE = Arrays.asList(
+ "nacos", "authority", "gateway", "ribbon", "feign", "hystrix", "e-commerce"
+ );
+
+ /**
+ * test 方法主要用于参数符不符合规则, 返回值是 boolean
+ * */
+ @Test
+ public void testPredicateTest() {
+
+ Predicate letterLengthLimit = s -> s.length() > 5;
+ MICRO_SERVICE.stream().filter(letterLengthLimit).forEach(System.out::println);
+ }
+
+ /**
+ * and 方法等同于我们的逻辑与 &&, 存在短路特性, 需要所有的条件都满足
+ * */
+ @Test
+ public void testPredicateAnd() {
+
+ Predicate letterLengthLimit = s -> s.length() > 5;
+ Predicate letterStartWith = s -> s.startsWith("gate");
+
+ MICRO_SERVICE.stream().filter(
+ letterLengthLimit.and(letterStartWith)
+ ).forEach(System.out::println);
+ }
+
+ /**
+ * or 等同于我们的逻辑或 ||, 多个条件主要一个满足即可
+ * */
+ @Test
+ public void testPredicateOr() {
+
+ Predicate letterLengthLimit = s -> s.length() > 5;
+ Predicate letterStartWith = s -> s.startsWith("gate");
+
+ MICRO_SERVICE.stream().filter(
+ letterLengthLimit.or(letterStartWith)
+ ).forEach(System.out::println);
+ }
+
+ /**
+ * negate 等同于我们的逻辑非 !
+ * */
+ @Test
+ public void testPredicateNegate() {
+
+ Predicate letterStartWith = s -> s.startsWith("gate");
+ MICRO_SERVICE.stream().filter(letterStartWith.negate()).forEach(System.out::println);
+ }
+
+ /**
+ * isEqual 类似于 equals(), 区别在于: 先判断对象是否为 NULL,
+ * 不为 NULL 再使用 equals 进行比较
+ * */
+ @Test
+ public void testPredicateIsEqual() {
+
+ Predicate equalGateway = s -> Predicate.isEqual("gateway").test(s);
+ MICRO_SERVICE.stream().filter(equalGateway).forEach(System.out::println);
+ }
+}
diff --git a/dev-protocol-springcloud/dev-protocol-springcloud-nacos/pom.xml b/dev-protocol-springcloud/dev-protocol-springcloud-nacos/pom.xml
index 6d17103..234fece 100644
--- a/dev-protocol-springcloud/dev-protocol-springcloud-nacos/pom.xml
+++ b/dev-protocol-springcloud/dev-protocol-springcloud-nacos/pom.xml
@@ -25,11 +25,19 @@
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
com.alibaba.cloud
spring-cloud-starter-alibaba-nacos-discovery
- 2.2.3.RELEASE
+
+
+ org.projectlombok
+ lombok
-
- org.projectlombok
- lombok
-
+
diff --git a/dev-protocol-springcloud/dev-protocol-springcloud-nacos/src/main/java/org/example/controller/NacosClientController.java b/dev-protocol-springcloud/dev-protocol-springcloud-nacos/src/main/java/org/example/controller/NacosClientController.java
new file mode 100644
index 0000000..ef1ad95
--- /dev/null
+++ b/dev-protocol-springcloud/dev-protocol-springcloud-nacos/src/main/java/org/example/controller/NacosClientController.java
@@ -0,0 +1,51 @@
+package org.example.controller;
+
+import lombok.extern.slf4j.Slf4j;
+import org.example.service.NacosClientService;
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * nacos client controller
+ * */
+@Slf4j
+@RestController
+@RequestMapping("/nacos-client")
+public class NacosClientController {
+
+ private final NacosClientService nacosClientService;
+// private final ProjectConfig projectConfig;
+
+
+ public NacosClientController(NacosClientService nacosClientService
+// ProjectConfig projectConfig
+ ) {
+ this.nacosClientService = nacosClientService;
+// this.projectConfig = projectConfig;
+ }
+
+
+ /**
+ * 根据 service id 获取服务所有的实例信息
+ * */
+ @GetMapping("/service-instance")
+ public List logNacosClientInfo(
+ @RequestParam(defaultValue = "dev-protocol-spring-cloud-nacos") String serviceId) {
+
+ log.info("coming in log nacos client info: [{}]", serviceId);
+ return nacosClientService.getNacosClientInfo(serviceId);
+ }
+
+/* *//**
+ * 动态获取 Nacos 中的配置信息
+ * *//*
+ @GetMapping("/project-config")
+ public ProjectConfig getProjectConfig() {
+ return projectConfig;
+ }*/
+}
diff --git a/dev-protocol-springcloud/dev-protocol-springcloud-nacos/src/main/resources/application.yml b/dev-protocol-springcloud/dev-protocol-springcloud-nacos/src/main/resources/bootstrap.yml
similarity index 86%
rename from dev-protocol-springcloud/dev-protocol-springcloud-nacos/src/main/resources/application.yml
rename to dev-protocol-springcloud/dev-protocol-springcloud-nacos/src/main/resources/bootstrap.yml
index f4eed9c..50d513c 100644
--- a/dev-protocol-springcloud/dev-protocol-springcloud-nacos/src/main/resources/application.yml
+++ b/dev-protocol-springcloud/dev-protocol-springcloud-nacos/src/main/resources/bootstrap.yml
@@ -1,11 +1,11 @@
server:
port: 8000
servlet:
- context-path: /e-commerce-nacos-client
+ context-path: /dev-protocol-spring-cloud-nacos
spring:
application:
- name: e-commerce-nacos-client # 应用名称也是构成 Nacos 配置管理 dataId 字段的一部分 (当 config.prefix 为空时)
+ name: dev-protocol-spring-cloud-nacos # 应用名称也是构成 Nacos 配置管理 dataId 字段的一部分 (当 config.prefix 为空时)
cloud:
nacos:
# 服务注册发现
@@ -64,11 +64,11 @@ spring:
# enabled: true
# 暴露端点
-#management:
-# endpoints:
-# web:
-# exposure:
-# include: '*'
-# endpoint:
-# health:
-# show-details: always
+management:
+ endpoints:
+ web:
+ exposure:
+ include: '*'
+ endpoint:
+ health:
+ show-details: always
diff --git a/dev-protocol-springcloud/dev-protocol-springcloud-nacos/src/main/resources/http/nacos-client.http b/dev-protocol-springcloud/dev-protocol-springcloud-nacos/src/main/resources/http/nacos-client.http
index 9a454e9..52b3860 100644
--- a/dev-protocol-springcloud/dev-protocol-springcloud-nacos/src/main/resources/http/nacos-client.http
+++ b/dev-protocol-springcloud/dev-protocol-springcloud-nacos/src/main/resources/http/nacos-client.http
@@ -1,13 +1,13 @@
### 查询服务实例信息
-GET http://127.0.0.1:8000/ecommerce-nacos-client/nacos-client/service-instance
+GET http://127.0.0.1:8000/dev-protocol-spring-cloud-nacos/nacos-client/service-instance
Accept: application/json
### 动态从 Nacos Server 中获取配置信息
-GET http://127.0.0.1:8000/ecommerce-nacos-client/nacos-client/project-config
+GET http://127.0.0.1:8000/dev-protocol-spring-cloud-nacos/nacos-client/project-config
Accept: application/json
### 查看 Sleuth 跟踪信息
-GET http://127.0.0.1:9001/imooc/ecommerce-nacos-client/sleuth/trace-info
+GET http://127.0.0.1:9001/imooc/dev-protocol-spring-cloud-nacos/sleuth/trace-info
Accept: application/json
e-commerce-user: eyJhbGciOiJSUzI1NiJ9.eyJlLWNvbW1lcmNlLXVzZXIiOiJ7XCJpZFwiOjE3LFwidXNlcm5hbWVcIjpcIkltb29jUWlueWlAaW1vb2MuY29tXCJ9IiwianRpIjoiMGIxNzQyYWItMWU3OC00OTZjLWIyNTAtMjNkZGQ1ZGEyZTU1IiwiZXhwIjoxNjI0MjA0ODAwfQ.QKGHzohSHdYDHzUVHpe9gNPUgzfkPwrSbB-WiMWYjLlt2tr9BufzZM8bSt-whb_bd0hKoC6rkYYO0WUVR67uSML-2yaTL1xMIn8GH9Flyig3rpO4vefL3Hp2TXIpwHHa7WlKsLzcUpNk9lxWs2B5k0ICdYCH_jD5Tx6N7CzfSUG9u4fOnVeM9UFE2nX_DURupUh_DKCc2oOoMeyCSR7Ma8-Ab4WQU3r-U0YivR8G1A0kmKOIoTeRhM3LcPuxUPh3rCbrjzMg--fexRGw0O38Qsby6pz-ku2IlTyFXY6_jNOG1BZR34-jBOnaIciP1TExw9bFumeuC2GcowTHJVH1Nw
token: imooc