最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用Feign調(diào)用注解組件(實(shí)現(xiàn)字段賦值功能)

 更新時(shí)間:2022年03月14日 14:42:57   作者:qq_42152947  
這篇文章主要介紹了使用Feign調(diào)用注解組件(實(shí)現(xiàn)字段賦值功能),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

使用注解的形式,裝配在id字段,自動(dòng)調(diào)用fegin賦值給目標(biāo)字段。

使用效果

1.先給vo類(lèi)中字段添加注解 

2.調(diào)用feignDataSetUtils.setData 方法  將vo類(lèi)放入 比如我的

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

調(diào)用前

 調(diào)用后 產(chǎn)生賦值。

利用類(lèi)字段注解的形式配置好對(duì)應(yīng)的fegin關(guān)系,達(dá)到自動(dòng)調(diào)用fegin的效果。

優(yōu)點(diǎn)

1.省略大部分代碼,只需配置注解,和編寫(xiě)fegin所需方法。

2.無(wú)其他重依賴(lài),適應(yīng)性強(qiáng)。

3.隨意裝配,不需要vo類(lèi)或者fegin類(lèi)繼承任何接口。

如何裝配

加入所有工具類(lèi)后,只需兩步。

先加入 以下類(lèi)

ApplicationContextProvider:

 
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
 
/**
 * @Version 1.0
 * @Author:yanch
 * @Date:2021-9-28
 * @Content:
 */
 
@Component
public class ApplicationContextProvider implements ApplicationContextAware {
    private static ApplicationContext applicationContextSpring;
 
    @Override
    public synchronized void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        applicationContextSpring = applicationContext;
    }
 
    /**
     * 通過(guò)class 獲取Bean
     */
    public static <T> T getBean(Class<T> clazz) {
        return applicationContextSpring.getBean(clazz);
    }
}

FeignColum:

 
import java.lang.annotation.*;
 
/**
 * @Version 1.0
 * @Author:yanch
 * @Date:2021-9-27
 * @Content:
 */
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FeignColum {
    /**
     * 目標(biāo)字段 當(dāng)前vo類(lèi)的想要賦值的字段名稱(chēng)
     *
     */
    String targetFieldName();
 
    /**
     *  當(dāng)前字段如果是string類(lèi)型且是用“,”分割的話就可以使用這個(gè)屬性 可以設(shè)置為“,”,該字段將會(huì)被“,”分割
     *
     */
    String split() default "";
 
    /**
     *  使用的feignType枚舉類(lèi)型
     *
     */
    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;
 
/**
 * @Version 1.0
 * @Author:yanch
 * @Date:2021-9-28
 * @Content:
 */
@Component
public class FeignDataSetUtils {
 
//    @Value("${appId}")
    private String appId;  
 
    /**
     * 補(bǔ)充User數(shù)據(jù)
     *
     * @param voList
     * @return
     */
    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);
        // 獲得數(shù)據(jù)dataMap 后面用來(lái)發(fā)送給feign
        Map<FeignType, List<Object>> idDataMap = buildDataMap(feignFieldsMap.keySet());
        // 遍歷所有注解
        // 遍歷所有攜帶注解的字段-獲得id集合
        putIdDataMap(feignFieldsMap, voList, idDataMap);
 
        // Feign返回結(jié)果集合
        Map<FeignType, Map<Object, Object>> feignResultMap = getFeignResultMap(idDataMap);
        // 遍歷所有
        // 遍歷所有攜帶注解的字段-添加集合
        putDataMap(feignFieldsMap, objectClass, voList, feignResultMap); 
        return voList;
    }
 
    /**
     * 添加Feign的Result數(shù)據(jù)
     * @return
     */
    private Map<FeignType, Map<Object, Object>> getFeignResultMap(Map<FeignType, List<Object>> idDataMap) {
        // 初始化Feign返回結(jié)果集合
        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))
                        ); 
            });
        });
 
//        // 獲得用戶(hù)集合
//        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;
    }
 
    /**
     * 遍歷所有攜帶注解的字段-獲得id集合
     *
     * @return
     */
    private void putIdDataMap(Map<FeignType, List<Field>> feignFieldsMap, List voList, Map<FeignType, List<Object>> idDataMap) {
        //遍歷所有數(shù)據(jù)
        voList.stream().forEach(entry -> {
            feignFieldsMap.keySet().stream().forEach(feignClass -> {
                feignFieldsMap.get(feignClass).stream().forEach(field -> {
                    FeignColum colum = field.getAnnotation(FeignColum.class);
                    field.setAccessible(true);
                    // 開(kāi)始添加id數(shù)據(jù)
                    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();
                    }
                }); 
            });
        });
        // 刪除沒(méi)有的數(shù)據(jù)
        idDataMap.values().removeIf(value -> CollectionUtils.isEmpty(value));
    }
 
    /**
     * 遍歷所有攜帶注解的字段-添加集合
     *
     * @return
     */
    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();
                        // 目標(biāo)字段
                        Field targetField = objectClass.getDeclaredField(targetFieldName);
                        targetField.setAccessible(true);
                        // 開(kāi)始添加用戶(hù)數(shù)據(jù)
                        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();
                    }
                });
            });
        });
    } 
 
    /**
     * 獲得需要的注解字段
     *
     * @param cls
     * @return
     */
    private Map<FeignType, List<Field>> getFieldsAnnotationMap(Class cls) {
        // 注解集合對(duì)象
        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);
                }
            });
        });
        // 刪除沒(méi)有的字段注解
        feignMap.values().removeIf(value -> CollectionUtils.isEmpty(value));
        return feignMap;
    }
 
    /**
     * 初始化注解map
     *
     * @return
     */
    private Map<FeignType, List<Field>> buildAnnotationMap() {
        return Arrays.stream(FeignType.values()).collect(Collectors.toMap(my -> my, my -> new ArrayList()));
    } 
 
    /**
     * 初始化字段數(shù)據(jù)map
     *
     * @return
     */
    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;
 
/**
 * @Version 1.0
 * @Author:yanch
 * @Date:2021-9-28
 * @Content:
 */
@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];
    }
}

剩下的兩塊代碼需要自己加?xùn)|西

  • FeignType:這個(gè)是用來(lái)給注解配置Feign的枚舉選項(xiàng),也就是你想要什么Feign就需要在FeignType中添加一次。

例如我的:

  
/**
 * @Version 1.0
 * @Author:yanch
 * @Date:2021-9-27
 * @Content:
 */
public enum FeignType {
    /**
     *手工配置1   UserInfoFeign 是選項(xiàng)名稱(chēng) 用來(lái)給注解配置使用
     */
    UserInfoFeign(),
    /**
     *手工配置2   UserInfoFeign2 是選項(xiàng)名稱(chēng) 用來(lái)給注解配置使用
     */
    UserInfoFeign2(); 
}
  • FeignFunctionMap:它的作用是用來(lái)綁定FeignType和IFeignFunction(Feign的方法)的關(guān)系。
  • 具體可以查看代碼理解。比如代碼里面的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; 
 
/**
 * @Version 1.0
 * @Author:yanch
 * @Date:2021-9-28
 * @Content:
 */
public class FeignFunctionMap {
    private static Map<FeignType, IFeignFunction> feignFunctionMap = new HashMap(); 
    static {
        /**
         * 用來(lái)綁定FeignType.UserInfoFeign 和Feign方法的關(guān)系(IFeignFunction)
         *手工配置1
         * IFeignFunction的第一個(gè)泛型是Feign的類(lèi),第二個(gè)是字段參數(shù)類(lèi)型。 比如我用的是String 存儲(chǔ)的id,這里就用String
         */
        // 用戶(hù)Feign
        put(FeignType.UserInfoFeign,new IFeignFunction<UserInfoFeign,String>() {
            @Override
            public  Map<String, Object> getBatch(List<String> idList) {
                // feign對(duì)象相當(dāng)于UserInfoFeign的實(shí)例化對(duì)象,appid你們可以不用管,這個(gè)是我的feign必須要攜帶的一個(gè)常量。
                // 為什么要返回一個(gè)Map<String, Object> ?  因?yàn)檫@將要用來(lái)做成字典,key是id,value是這個(gè)feign根據(jù)這個(gè)id調(diào)用來(lái)的值
                return feign.getBatch(idList, appId).stream().collect(Collectors.toMap(UserVo::getId, my -> (Object) my));
            } 
        });
        /**
         * 用來(lái)綁定FeignType.UserInfoFeign2 和Feign方法的關(guān)系(IFeignFunction)
         *手工配置2
         * IFeignFunction的第一個(gè)泛型是Feign的類(lèi),第二個(gè)是字段參數(shù)類(lèi)型。 比如我用的是Long 存儲(chǔ)的id,這里就用Long
         */
        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));
            }
 
        });  
    }  
 
    /**
     *--------------------------以下無(wú)需配置
     */
    /**
     *@param feignType FeignType名稱(chēng)
     *@param iFeignFunction feign方法實(shí)現(xiàn)方式
     */
    public  static void put(FeignType feignType,IFeignFunction iFeignFunction){
        feignFunctionMap.put(feignType,iFeignFunction);
    }
 
    public static Map<FeignType, IFeignFunction> getFeignFunctionMap() {
        return feignFunctionMap;
    }  
}

如果把自己的FeignType和FeignFunctionMap配置完成后就可以在自己的類(lèi)中加入注解了。

比如下面是我的vo類(lèi)。

之后放入feignDataSetUtils.setData(Stream.of(vo).collect(Collectors.toList()))當(dāng)中就能夠賦值了。

上面的代碼沒(méi)有必要放出來(lái)所以我就已圖片的形式展示出來(lái)了。

FeignColum注解類(lèi)的三個(gè)屬性用意:

  • targetFieldName:用來(lái)記錄目標(biāo)賦值的字段名稱(chēng)     
  • split:用來(lái)切割字符串的分割符號(hào),比如我的 字段是allUserId的值是 "1;2"  那我就需要配置        split = ";",且目標(biāo)字段也必須是List接收。
  • feignType:用來(lái)綁定使用的feginType的枚舉類(lèi)型。

特殊需求

1.假如我的feign的方法每次請(qǐng)求除了攜帶id還需要攜帶一個(gè)常量參數(shù)訪問(wèn)該怎么辦?

這個(gè)可以是用全局搜索參看 appId的使用方式。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot最常用的50個(gè)注解總結(jié)(全是干貨!)

    SpringBoot最常用的50個(gè)注解總結(jié)(全是干貨!)

    SpringBoot提供多種注解簡(jiǎn)化配置與啟動(dòng)流程,如@SpringBootAppication、@RestController、@RequestMapping等,這篇文章主要介紹了SpringBoot最常用的50個(gè)注解的相關(guān)資料,需要的朋友可以參考下
    2024-09-09
  • tk.mybatis擴(kuò)展通用接口使用詳解

    tk.mybatis擴(kuò)展通用接口使用詳解

    這篇文章主要介紹了tk.mybatis擴(kuò)展通用接口使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • spring mvc中的@PathVariable獲得請(qǐng)求url中的動(dòng)態(tài)參數(shù)

    spring mvc中的@PathVariable獲得請(qǐng)求url中的動(dòng)態(tài)參數(shù)

    本文主要介紹了spring mvc中的@PathVariable獲得請(qǐng)求url中的動(dòng)態(tài)參數(shù)的代碼。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-02-02
  • Java多線程實(shí)現(xiàn)模擬12306火車(chē)站售票系統(tǒng)

    Java多線程實(shí)現(xiàn)模擬12306火車(chē)站售票系統(tǒng)

    12360火車(chē)票售票系統(tǒng)基本上大家都用過(guò),那你知道是怎么實(shí)現(xiàn)的嗎,今天我們就模擬12306火車(chē)站售票系統(tǒng)來(lái)實(shí)現(xiàn),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • 詳解JDK中ExecutorService與Callable和Future對(duì)線程的支持

    詳解JDK中ExecutorService與Callable和Future對(duì)線程的支持

    這篇文章主要介紹了詳解JDK中ExecutorService與Callable和Future對(duì)線程的支持的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • Java?Spring?boot日期和時(shí)間統(tǒng)一設(shè)置三種方法

    Java?Spring?boot日期和時(shí)間統(tǒng)一設(shè)置三種方法

    時(shí)間和日期的統(tǒng)一設(shè)置在項(xiàng)目中經(jīng)常是會(huì)遇到的,下面這篇文章主要給大家介紹了關(guān)于Java?Spring?boot日期和時(shí)間統(tǒng)一設(shè)置的三種方法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-08-08
  • Java使用list集合remove需要注意的事項(xiàng)(使用示例)

    Java使用list集合remove需要注意的事項(xiàng)(使用示例)

    List集合的一個(gè)特點(diǎn)是它其中的元素是有序的,也就是說(shuō)元素的下標(biāo)是根據(jù)插入的順序來(lái)的,在刪除頭部或者中間的一個(gè)元素后,后面的元素下標(biāo)會(huì)往前移動(dòng),本文給大家介紹Java使用list集合remove需要注意的事項(xiàng),感興趣的朋友一起看看吧
    2022-01-01
  • 三分鐘快速掌握J(rèn)ava中枚舉(enum)

    三分鐘快速掌握J(rèn)ava中枚舉(enum)

    enum的全稱(chēng)為enumeration, 是 JDK 1.5中引入的新特性,存放在 java.lang包中。下面這篇文章是我在使用enum過(guò)程中的一些經(jīng)驗(yàn)和總結(jié),分享出來(lái)方便大家快速的掌握J(rèn)ava中枚舉(enum),有需要的朋友們下面跟著小編來(lái)一起看看吧。
    2016-12-12
  • SpringCloud gateway如何修改返回?cái)?shù)據(jù)

    SpringCloud gateway如何修改返回?cái)?shù)據(jù)

    這篇文章主要介紹了SpringCloud gateway如何修改返回?cái)?shù)據(jù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • java常見(jiàn)的字符串操作和日期操作匯總

    java常見(jiàn)的字符串操作和日期操作匯總

    本文主要對(duì)java 常見(jiàn)的字符串操作和日期操作進(jìn)行整理。具有一定的參考價(jià)值,需要的朋友一起來(lái)看下吧
    2016-12-12

最新評(píng)論

隆昌县| 苏尼特左旗| 广平县| 凉城县| 景德镇市| 德江县| 石景山区| 台安县| 图们市| 新龙县| 吴旗县| 祁连县| 榆中县| 宁陕县| 三亚市| 岱山县| 涿鹿县| 县级市| 安丘市| 平乐县| 同仁县| 扎鲁特旗| 章丘市| 嘉黎县| 建宁县| 青岛市| 长乐市| 冕宁县| 桐梓县| 天镇县| 丹东市| 福鼎市| 文昌市| 寻甸| 慈溪市| 达日县| 太仆寺旗| 建德市| 荔浦县| 平乐县| 大安市|