aspect实现mock-feign接口

简介: 该代码为一个用于Feign接口的模拟(Mock)实现类`FeignMockAspect`,通过切面编程方式对带有`@FeignClient`注解的接口提供模拟响应。在非生产环境中,根据特定配置从Redis中获取Mock数据并转换为对应类型的对象返回,以减少对外部系统的依赖和提高测试效率。使用Hutool工具类和Spring Data Redis进行数据处理与存储操作。

package com.ph.sp.integration.advice;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Pair;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

/**

  • feign接口mock
    */
    @Component
    @Aspect
    @Order(-1)
    @Slf4j
    public class FeignMockAspect {

    @Pointcut("@within(org.springframework.cloud.openfeign.FeignClient)")
    public void typeCut() {
    }

    @Around("typeCut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {

     if (isPrd) {
         return pjp.proceed();
     }
     Pair<Boolean, String> mockConfig = getMockConfig(pjp);
     Boolean haveConfig = mockConfig.getKey();
     String mockResp = mockConfig.getValue();
     if (!haveConfig || mockResp == null) {
         return pjp.proceed();
     }
     return transMockResp2Obj(pjp, mockResp);
    

    }

    private Object transMockResp2Obj(ProceedingJoinPoint pjp, String mockResp) {

     Method method = ((MethodSignature) pjp.getSignature()).getMethod();
     try {
         Type returnType = method.getGenericReturnType();
         return JsonUtil.json2obj(mockResp, returnType);
     } catch (Exception e) {
         log.warn("trans GenericReturnType error~", e);
         Type returnType = method.getReturnType();
         return JsonUtil.json2obj(mockResp, returnType);
     }
    

    }

    private Pair getMockConfig(ProceedingJoinPoint pjp) {

     String body = JsonUtil.writeValueToString(pjp.getArgs());
     String uri = getUri(pjp);
     HashOperations<String, String, String> operation = hashTemplate.opsForHash();
     Map<String, String> mockConfig = operation.entries("A_MOCK_" + uri);
     if (CollUtil.isEmpty(mockConfig)) {
         return new Pair<>(false, null);
     }
     return new Pair<>(true, getMockResp(body, mockConfig));
    

    }

    private String getMockResp(String body, Map mockConfig) {

     Set<Map.Entry<String, String>> entries = mockConfig.entrySet();
     for (Map.Entry<String, String> entry : entries) {
         if (StrUtil.contains(body, entry.getKey())) {
             log.info("命中入参,返回mock数据 reqPattern:{}", entry.getKey());
             return Base64Utils.decode(entry.getValue());
         }
     }
     log.info("未命中入参,请求真实数据");
     return null;
    

    }

    private static String getUri(ProceedingJoinPoint pjp) {

     Method method = ((MethodSignature) pjp.getSignature()).getMethod();
     return Optional.ofNullable(method.getAnnotation(PostMapping.class)).map(PostMapping::value).map(e -> e[0])
             .orElseGet(() -> Optional.ofNullable(method.getAnnotation(GetMapping.class))
                     .map(GetMapping::value).map(e -> e[0]).orElse(""));
    

    }

    @Resource
    private RedisTemplate> hashTemplate;
    }

相关文章
|
缓存 Java API
【云原生】Spring Cloud Gateway的底层原理与实践方法探究
【云原生】Spring Cloud Gateway的底层原理与实践方法探究
|
缓存 Linux 开发工具
CentOS 7- 配置阿里镜像源
阿里镜像官方地址http://mirrors.aliyun.com/ 1、点击官方提供的相应系统的帮助 :2、查看不同版本的系统操作: 下载源1、安装wget yum install -y wget2、下载CentOS 7的repo文件wget -O /etc/yum.
261161 0
|
IDE Java 测试技术
单元测试问题之Mockito 3.4mock静态方法如何解决
单元测试问题之Mockito 3.4mock静态方法如何解决
880 1
springCloud之服务降级熔断Hystrix、OpenFeign
springCloud之服务降级熔断Hystrix、OpenFeign
1081 0
|
存储 自然语言处理 Java
如何在Java中实现国际化与本地化
如何在Java中实现国际化与本地化
|
机器学习/深度学习 人工智能
|
Java API Nacos
spring.config.import 是一个 Spring Cloud Config Server 的属性,
spring.config.import 是一个 Spring Cloud Config Server 的属性,【1月更文挑战第25天】【1月更文挑战第123篇】
2677 1
|
存储 缓存 NoSQL
基于SpringBoot+Redis解决缓存与数据库一致性、缓存穿透、缓存雪崩、缓存击穿问题
这篇文章讨论了在使用SpringBoot和Redis时如何解决缓存与数据库一致性问题、缓存穿透、缓存雪崩和缓存击穿问题,并提供了相应的解决策略和示例代码。
450 0
|
canal 存储 关系型数据库
mysql数据同步到clickhouse
mysql数据同步到clickhouse
1455 0