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;
    }

相关文章
|
Windows
『Consul』Consul数据持久化配置并且注册为Windows服务
📣读完这篇文章里你能收获到 - Consul数据持久化配置并且注册为Windows服务
1917 0
『Consul』Consul数据持久化配置并且注册为Windows服务
|
Java 测试技术 开发者
必学!Spring Boot 单元测试、Mock 与 TestContainer 的高效使用技巧
【10月更文挑战第18天】 在现代软件开发中,单元测试是保证代码质量的重要手段。Spring Boot提供了强大的测试支持,使得编写和运行测试变得更加简单和高效。本文将深入探讨Spring Boot的单元测试、Mock技术以及TestContainer的高效使用技巧,帮助开发者提升测试效率和代码质量。
1605 2
|
人工智能 自然语言处理 测试技术
有没有可能不微调也能让大模型准确完成指定任务?(少样本学习)
对于我这种正在从0到1构建AI产品的一人公司来说,Few Shots学习的最大价值在于:用最少的资源获得最大的效果。我不需要大量的标注数据,不需要复杂的模型训练,只需要精心设计几个示例,就能让大模型快速理解我的业务场景。
676 43
|
10月前
|
Java 大数据 Apache
Excel工具-HUTOOL-输出Excel
Hutool基于Apache POI封装了Excel读写功能,提供ExcelWriter和BigExcelWriter类,支持写出List、Map、Bean等数据类型到Excel,可自定义样式、多sheet操作,并解决大数据量导出时的内存溢出问题,适用于文件导出、客户端下载等场景。
|
10月前
|
Java 大数据 Apache
Excel工具-HUTOOL-输出Excel
基于Hutool与Apache POI,封装Excel写入功能,提供ExcelWriter和BigExcelWriter,支持List、Map、Bean等数据类型导出,可自定义样式、多Sheet操作,并避免内存溢出,适用于高效生成Excel文件及Web下载场景。
481 0
|
机器学习/深度学习 算法
《动量法:梯度下降算法的加速引擎》
动量法(Momentum)改进了梯度下降算法收敛慢、易震荡和陷入局部最优等问题。通过引入历史梯度信息,动量法加速了参数更新,使模型在平坦区域也能快速收敛。它平滑了更新方向,减少了高曲率区域的震荡,增强了逃离局部最优的能力。此外,动量法提高了优化效率,减少了迭代次数,并可与其他优化算法结合,进一步提升训练效果。总之,动量法显著改善了梯度下降的性能,成为深度学习中不可或缺的优化技术。
763 2
|
Java 关系型数据库 MySQL
SpringBoot 导出多个Excel文件,压缩成.zip格式下载
SpringBoot 导出多个Excel文件,压缩成.zip格式下载
1584 0
SpringBoot 导出多个Excel文件,压缩成.zip格式下载
|
监控 关系型数据库 MySQL
MySQL自增ID耗尽应对策略:技术解决方案全解析
在数据库管理中,MySQL的自增ID(AUTO_INCREMENT)属性为表中的每一行提供了一个唯一的标识符。然而,当自增ID达到其最大值时,如何处理这一情况成为了数据库管理员和开发者必须面对的问题。本文将探讨MySQL自增ID耗尽的原因、影响以及有效的应对策略。
887 3
|
Java 数据处理
|
机器学习/深度学习 人工智能

热门文章

最新文章