返回顶部
首页 > 资讯 > 后端开发 > Python >使用Feign调用注解组件(实现字段赋值功能)
  • 769
分享到

使用Feign调用注解组件(实现字段赋值功能)

2024-04-02 19:04:59 769人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录使用效果优点如何装配特殊需求使用注解的形式,装配在id字段,自动调用fegin赋值给目标字段。 使用效果 1.先给vo类中字段添加注解  2.调用feignDataS

使用注解的形式,装配在id字段,自动调用fegin赋值给目标字段。

使用效果

1.先给vo类中字段添加注解 

2.调用feignDataSetUtils.setData 方法  将vo类放入 比如我的

feignDataSetUtils.setData(Stream.of(vo).collect(Collectors.toList()));

调用前

 调用后 产生赋值。

利用类字段注解的形式配置好对应的fegin关系,达到自动调用fegin的效果。

优点

1.省略大部分代码,只需配置注解,和编写fegin所需方法。

2.无其他重依赖,适应性强。

3.随意装配,不需要vo类或者fegin类继承任何接口。

如何装配

加入所有工具类后,只需两步。

先加入 以下类

ApplicationContextProvider:

 
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
 

 
@Component
public class ApplicationContextProvider implements ApplicationContextAware {
    private static ApplicationContext applicationContextSpring;
 
    @Override
    public synchronized void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        applicationContextSpring = applicationContext;
    }
 
    
    public static <T> T getBean(Class<T> clazz) {
        return applicationContextSpring.getBean(clazz);
    }
}

FeignColum:

 
import java.lang.annotation.*;
 

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FeignColum {
    
    String targetFieldName();
 
    
    String split() default "";
 
    
    FeignType feignType();
}

FeignDataSetUtils:

 
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
 
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;
 

@Component
public class FeignDataSetUtils {
 
//    @Value("${appId}")
    private String appId;  
 
    
    public List setData(List voList) {
        if (CollectionUtils.isEmpty(voList)) {
            return voList;
        }
        Object object = voList.get(0);
        Class objectClass = object.getClass();
        // 获得feign的class为key Field集合为value的map
        Map<FeignType, List<Field>> feignFieldsMap = getFieldsAnnotationMap(objectClass);
        // 获得数据dataMap 后面用来发送给feign
        Map<FeignType, List<Object>> idDataMap = buildDataMap(feignFieldsMap.keySet());
        // 遍历所有注解
        // 遍历所有携带注解的字段-获得id集合
        putIdDataMap(feignFieldsMap, voList, idDataMap);
 
        // Feign返回结果集合
        Map<FeignType, Map<Object, Object>> feignResultMap = getFeignResultMap(idDataMap);
        // 遍历所有
        // 遍历所有携带注解的字段-添加集合
        putDataMap(feignFieldsMap, objectClass, voList, feignResultMap); 
        return voList;
    }
 
    
    private Map<FeignType, Map<Object, Object>> getFeignResultMap(Map<FeignType, List<Object>> idDataMap) {
        // 初始化Feign返回结果集合
        Map<FeignType, Map<Object, Object>> feignResultMap = new HashMap();
 
        Map<FeignType, IFeignFunction> feignFunctionMap = FeignFunctionMap.getFeignFunctionMap();
        idDataMap.keySet().forEach(feignType -> {
            IFeignFunction feignFunction = feignFunctionMap.get(feignType);
            Optional.ofNullable(feignFunction).ifPresent(m -> {
                m.setAppId(appId);
                m.setFeign(ApplicationContextProvider.getBean(feignType.getFeignClass()));
                Optional.ofNullable(idDataMap.get(feignType)).ifPresent(idList ->
                                feignResultMap.put(feignType, m.getBatch(idList))
                        ); 
            });
        });
 
//        // 获得用户集合
//        Map<String, Object> userVoMap= Optional.ofNullable(idDataMap.get(FeignType.UserInfoFeign.getFeignClass())).map(m->userInfoFeign.getBatch(m,appId).stream().collect(Collectors.toMap(UserVo::getId, my->(Object)my))).orElse(null) ;
//        Optional.ofNullable(userVoMap).ifPresent(p->
//                        feignResultMap.put(FeignType.UserInfoFeign.getFeignClass(),p)
//                );
 
        return feignResultMap;
    }
 
    
    private void putIdDataMap(Map<FeignType, List<Field>> feignFieldsMap, List voList, Map<FeignType, List<Object>> idDataMap) {
        //遍历所有数据
        voList.stream().forEach(entry -> {
            feignFieldsMap.keySet().stream().forEach(feignClass -> {
                feignFieldsMap.get(feignClass).stream().forEach(field -> {
                    FeignColum colum = field.getAnnotation(FeignColum.class);
                    field.setAccessible(true);
                    // 开始添加id数据
                    try {
                        if (StringUtils.isEmpty(colum.split())) {
                            Optional.ofNullable(field.get(entry)).filter(f -> !ObjectUtils.isEmpty(f)).ifPresent(
                                    fieldValue -> idDataMap.get(colum.feignType()).add(fieldValue));
                        } else {
                            Optional.ofNullable(field.get(entry)).map(m -> (String) m).filter(f -> StringUtils.isNotEmpty(f)).ifPresent(
                                    fieldValue -> idDataMap.get(colum.feignType()).addAll(Arrays.stream(fieldValue.split(colum.split())).collect(Collectors.toList())));
                        }
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }); 
            });
        });
        // 删除没有的数据
        idDataMap.values().removeIf(value -> CollectionUtils.isEmpty(value));
    }
 
    
    private void putDataMap(Map<FeignType, List<Field>> feignFieldsMap, Class objectClass, List voList, Map<FeignType, Map<Object, Object>> resultMap) {
        if (CollectionUtils.isEmpty(feignFieldsMap) || CollectionUtils.isEmpty(resultMap)) {
            return;
        }
        voList.stream().forEach(entry -> {
            feignFieldsMap.keySet().stream().forEach(feignType -> {
                Map<Object, Object> voMap = resultMap.get(feignType);
                feignFieldsMap.get(feignType).stream().forEach(field -> {
                    try {
                        FeignColum colum = field.getAnnotation(FeignColum.class);
                        String targetFieldName = colum.targetFieldName();
                        // 目标字段
                        Field targetField = objectClass.getDeclaredField(targetFieldName);
                        targetField.setAccessible(true);
                        // 开始添加用户数据
                        if (StringUtils.isEmpty(colum.split())) {
                            Optional.ofNullable(field.get(entry)).filter(f -> !ObjectUtils.isEmpty(f)).ifPresent(
                                    fieldValue -> {
                                        Object object = voMap.get(fieldValue);
                                        try {
                                            targetField.set(entry, object);
                                        } catch (IllegalAccessException e) {
                                            e.printStackTrace();
                                        }
                                    });
                        } else {
                            Optional.ofNullable(field.get(entry)).map(m -> (String) m).filter(f -> StringUtils.isNotEmpty(f)).ifPresent(
                                    fieldValue -> {
                                        try {
                                            Object object = Arrays.stream(fieldValue.split(colum.split())).map(m -> {
                                                return voMap.get(m);
                                            }).collect(Collectors.toList());
                                            targetField.set(entry, object);
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                        }
                                    });
                        }
                    } catch (NoSuchFieldException | IllegalAccessException e) {
                        e.printStackTrace();
                    }
                });
            });
        });
    } 
 
    
    private Map<FeignType, List<Field>> getFieldsAnnotationMap(Class cls) {
        // 注解集合对象
        Map<FeignType, List<Field>> feignMap = buildAnnotationMap();
        // 字段遍历
        Arrays.stream(cls.getDeclaredFields()).forEach(field -> {
            feignMap.keySet().stream().forEach(feignClass -> {
                if (field.isAnnotationPresent(FeignColum.class)) {
                    FeignColum colum = field.getAnnotation(FeignColum.class);
                    if(colum.feignType()!=feignClass){
                        return;
                    }
                    feignMap.get(colum.feignType()).add(field);
                }
            });
        });
        // 删除没有的字段注解
        feignMap.values().removeIf(value -> CollectionUtils.isEmpty(value));
        return feignMap;
    }
 
    
    private Map<FeignType, List<Field>> buildAnnotationMap() {
        return Arrays.stream(FeignType.values()).collect(Collectors.toMap(my -> my, my -> new ArrayList()));
    } 
 
    
    private Map<FeignType, List<Object>> buildDataMap(Collection<FeignType> collection) {
        return collection.stream().collect(Collectors.toMap(my -> my, my -> new ArrayList()));
    }
}

IFeignFunction:

 
import lombok.Data; 
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
 

@Data
public abstract class IFeignFunction<T,E> {
    Class<T> clazz;
    T feign;
    String appId;
    public IFeignFunction(){
        doGetClass();
    }
    public abstract Map<E, Object> getBatch(List<E> idList);
 
    public void doGetClass() {
        Type genType = this.getClass().getGenericSuperclass();
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        this.clazz = (Class<T>) params[0];
    }
}

剩下的两块代码需要自己加东西

  • FeignType:这个是用来给注解配置Feign的枚举选项,也就是你想要什么Feign就需要在FeignType中添加一次。

例如我的:

  

public enum FeignType {
    
    UserInfoFeign(),
    
    UserInfoFeign2(); 
}
  • FeignFunctionMap:它的作用是用来绑定FeignType和IFeignFunction(Feign的方法)的关系。
  • 具体可以查看代码理解。比如代码里面的put(FeignType.UserInfoFeign 。。。。和put(FeignType.UserInfoFeign2.。。。。
 
import com.xxx.xxx.sdk.feign.UserInfoFeign;
import com.xxx.xxx.sdk.vo.UserVo; 
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; 
 

public class FeignFunctionMap {
    private static Map<FeignType, IFeignFunction> feignFunctionMap = new HashMap(); 
    static {
        
        // 用户Feign
        put(FeignType.UserInfoFeign,new IFeignFunction<UserInfoFeign,String>() {
            @Override
            public  Map<String, Object> getBatch(List<String> idList) {
                // feign对象相当于UserInfoFeign的实例化对象,appid你们可以不用管,这个是我的feign必须要携带的一个常量。
                // 为什么要返回一个Map<String, Object> ?  因为这将要用来做成字典,key是id,value是这个feign根据这个id调用来的值
                return feign.getBatch(idList, appId).stream().collect(Collectors.toMap(UserVo::getId, my -> (Object) my));
            } 
        });
        
        put(FeignType.UserInfoFeign2,new IFeignFunction<UserInfoFeign,Long>() {
            @Override
            public  Map<Long, Object> getBatch(List<Long> idList) {
                return feign.getBatch(idList.stream().map(m->String.valueOf(m)).collect(Collectors.toList()), appId).stream().collect(Collectors.toMap( my ->Long.valueOf(my.getId()), my -> (Object) my));
            }
 
        });  
    }  
 
    
    
    public  static void put(FeignType feignType,IFeignFunction iFeignFunction){
        feignFunctionMap.put(feignType,iFeignFunction);
    }
 
    public static Map<FeignType, IFeignFunction> getFeignFunctionMap() {
        return feignFunctionMap;
    }  
}

如果把自己的FeignType和FeignFunctionMap配置完成后就可以在自己的类中加入注解了。

比如下面是我的vo类。

之后放入feignDataSetUtils.setData(Stream.of(vo).collect(Collectors.toList()))当中就能够赋值了。

上面的代码没有必要放出来所以我就已图片的形式展示出来了。

FeignColum注解类的三个属性用意:

  • targetFieldName:用来记录目标赋值的字段名称     
  • split:用来切割字符串的分割符号,比如我的 字段是allUserId的值是 "1;2"  那我就需要配置        split = ";",且目标字段也必须是List接收。
  • feignType:用来绑定使用的feginType的枚举类型。

特殊需求

1.假如我的feign的方法每次请求除了携带id还需要携带一个常量参数访问该怎么办?

这个可以是用全局搜索参看 appId的使用方式。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: 使用Feign调用注解组件(实现字段赋值功能)

本文链接: https://lsjlt.com/news/142418.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 使用Feign调用注解组件(实现字段赋值功能)
    目录使用效果优点如何装配特殊需求使用注解的形式,装配在id字段,自动调用fegin赋值给目标字段。 使用效果 1.先给vo类中字段添加注解  2.调用feignDataS...
    99+
    2024-04-02
  • 解决使用mybatis取值,字段赋值错误的问题
    目录使用mybatis取值,字段赋值错误mybatis映射赋值失败错误输出错误造成原因解决方法使用mybatis取值,字段赋值错误  我在读取数据库的表信息时,出现了不同字...
    99+
    2024-04-02
  • 使用Ajax和forms组件怎么实现注册功能
    这期内容当中小编将会给大家带来有关使用Ajax和forms组件怎么实现注册功能,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。前端HTML<!DOCTYPE html>{% ...
    99+
    2023-06-08
  • 使用注解实现Redis缓存功能
    本文实例为大家分享了使用注解实现Redis缓存功能的具体代码,供大家参考,具体内容如下 非关系型内存数据库,有持久化操作, C语言编写的key,value存储系统(区别于mysql的二维表格的形式存储。) rdb:周期性...
    99+
    2022-07-28
    Redis 注解 缓存
  • SpringMVC使用注解实现登录功能
    本文实例为大家分享了SpringMVC使用注解实现登录的具体代码,供大家参考,具体内容如下 一、使用Component\Controller\Service\Repository四大...
    99+
    2024-04-02
  • 使用fileupload组件实现文件上传功能
    使用fileupload组件实现文件上传功能可以按照以下步骤进行:1. 导入相关文件和库:首先,需要导入jQuery库和fileup...
    99+
    2023-08-14
    fileupload
  • Spring中如何使用@Value注解实现给Bean属性赋值
    目录属性赋值@Value注解的定义:测试1.在添加了Spring依赖的Maven项目中创建2.在resources目录下创建一个配置文件person.properties3.创建配置...
    99+
    2024-04-02
  • 如何使用fileupload组件实现文件上传功能
    要使用fileupload组件实现文件上传功能,你需要进行以下步骤:1. 在HTML文件中,添加一个文件上传的input元素,设置t...
    99+
    2023-08-14
    fileupload
  • Python调用百度AI实现颜值评分功能
    目录一、调用百度接口进行人脸属性识别二、根据年龄和性别对颜值进行评价三、批量识别人脸属性四、自定义窗口语音播报颜值得分五、明星颜值评价一、调用百度接口进行人脸属性识别 安装好baid...
    99+
    2024-04-02
  • ReactRouterV5:使用HOC组件实现路由拦截功能
    目录前言一、创建一个HOC组件二、使用withRouter组件三、实现路由拦截前言 在Web应用程序中,需要对一些页面进行访问限制,只允许已经登录的用户访问受保护的页面。React ...
    99+
    2023-03-14
    React Router 路由拦截 React 路由拦截
  • 如何使用批处理实现注册表危险组件删除功能
    这篇文章主要介绍如何使用批处理实现注册表危险组件删除功能,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!把这个存成bat文件运行,保你服务器最基本的安全! 代码如下::: 注册表相关设定 reg delete HKEY...
    99+
    2023-06-08
  • SpringBoot使用@Cacheable注解实现缓存功能流程详解
    目录一、Spring从3.1开始支持Cache二、@Cacheable常用属性1、value/cacheNames2、key3、condition4、unless5、keyGener...
    99+
    2023-01-12
    SpringBoot @Cacheable注解 SpringBoot @Cacheable实现缓存
  • vue中怎么利用复合组件实现注册表单功能
    本篇文章给大家分享的是有关vue中怎么利用复合组件实现注册表单功能,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。具体内容如下<!doct...
    99+
    2024-04-02
  • 怎么使用Spring注解实现循环重试功能
    这篇文章主要介绍“怎么使用Spring注解实现循环重试功能”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用Spring注解实现循环重试功能”文章能帮助大家解决问题。一、@Retryable是什...
    99+
    2023-07-05
  • 使用自定义Json注解实现输出日志字段脱敏
    自定义Json注解实现输出日志字段脱敏 背景 在日志输出的时候,有时会输出一些用户的敏感信息,如手机号,身份证号,银行卡号等,现需要对这些信息在日志输出的时候进行脱敏处理 思路 使用...
    99+
    2024-04-02
  • Android使用http实现注册登录功能
    在项目中实现注册登录有很多种方式,一般对于初学者来说,不使用框架,采用http的post和get请求后台服务器,是一种更好理解底层源码的方式。使用框架实现注册登录虽然比自己封装pos...
    99+
    2024-04-02
  • Python怎么调用百度AI实现颜值评分功能
    本篇内容主要讲解“Python怎么调用百度AI实现颜值评分功能”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python怎么调用百度AI实现颜值评分功能”吧!一、调用百度接口进行人脸属性识别安装...
    99+
    2023-06-21
  • 使用Angular CDK实现一个Service弹出Toast组件功能
    目录1.环境安装2.创建Toast组件和ToastService2.1编写Toast组件和样式在Angular中,官方团队在开发Material组件库的同时,顺手做了一套Compon...
    99+
    2024-04-02
  • uniapp使用u-upload组件来实现图片上传功能
    目录前言一、官方示例用法二、关闭自动上传,使用手动上传的方式,代码 html 代码总结分析前言 在使用 uniapp 开发的微信小程序中使用了图片上传功能,使用了 uniapp 的图...
    99+
    2023-01-03
    uniapp怎么上传图片 uniapp u-upload组件 uniapp上传文件
  • 如何使用springboot+vue组件实现接口断言功能
    本文小编为大家详细介绍“如何使用springboot+vue组件实现接口断言功能”,内容详细,步骤清晰,细节处理妥当,希望这篇“如何使用springboot+vue组件实现接口断言功能”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一...
    99+
    2023-07-06
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作