亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

不使用SpringBoot如何將原生Feign集成到Spring中來簡化http調用

標簽:
Java

在微服务架构中,如果使用得是SpringCloud,那么只需要集成SpringFeign就可以了,SpringFeign可以很友好的帮我们进行服务请求,对象解析等工作。

然而SpingCloud是依赖于SpringBoot的。在老的Spring项目中通常是没有集成SpringBoot,那么我们又该如何使用Feign组件进行调用呢?

这种情况下就只能使用原生Feign了,Feign使用手册:https://www.cnblogs.com/chenkeyu/p/9017996.html

使用原生Feign的两个问题:

  一、原生Feign只能一次解析一个接口,生成对应的请求代理对象,如果一个包里有多个调用接口就要多次解析非常麻烦。

  二、Feign生成的调用代理只是一个普通对象,该如何注册到Spring中,以便于我们可以使用@Autowired随时注入。

解决方案:

  一、针对多次解析的问题,可以通过指定扫描包路径,然后对包中的类依次解析。使用工具:https://github.com/lukehutch/fast-classpath-scanner

  二、实现BeanFactoryPostProcessor接口,扩展Spring容器功能。

具体代码:

  maven依赖:

复制代码

<dependency>
            <groupId>com.netflix.feign</groupId>
            <artifactId>feign-core</artifactId>
            <version>8.18.0</version>
        </dependency>
        <dependency>
            <groupId>com.netflix.feign</groupId>
            <artifactId>feign-jackson</artifactId>
            <version>8.18.0</version>
        </dependency>
        <dependency>
            <groupId>io.github.lukehutch</groupId>
            <artifactId>fast-classpath-scanner</artifactId>
            <version>2.18.1</version>
        </dependency>

复制代码

  自定义注解:在扫描接口的过程中,可以通过一个自定义注解,来区分Feign接口并且指定调用的服务Url

复制代码

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface FeignApi {
   /**
    * 调用的服务地址
    * @return
    */
   String serviceUrl();
}

复制代码

  生成Feign代理并注册到Spring实现类:

复制代码

import feign.Feign;import feign.Request;import feign.Retryer;import feign.jackson.JacksonDecoder;import feign.jackson.JacksonEncoder;import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;import io.github.lukehutch.fastclasspathscanner.scanner.ScanResult;import org.springframework.beans.factory.config.BeanFactoryPostProcessor;import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;import org.springframework.stereotype.Component;import java.util.List;

@Componentpublic class FeignClientRegister implements BeanFactoryPostProcessor{    //扫描的接口路径
    private String  scanPath="com.xxx.api";

    @Override    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        List<String> classes = scan(scanPath);        if(classes==null){            return ;
        }
        System.out.println(classes);
        Feign.Builder builder = getFeignBuilder();        if(classes.size()>0){            for (String claz : classes) {
                Class<?> targetClass = null;                try {
                    targetClass = Class.forName(claz);
                    String url=targetClass.getAnnotation(FeignApi.class).serviceUrl();                    if(url.indexOf("http://")!=0){
                        url="http://"+url;
                    }
                    Object target = builder.target(targetClass, url);
                    beanFactory.registerSingleton(targetClass.getName(), target);
                } catch (Exception e) {                    throw new RuntimeException(e.getMessage());
                }
            }
        }
    }    public Feign.Builder getFeignBuilder(){
        Feign.Builder builder = Feign.builder()
                .encoder(new JacksonEncoder())
                .decoder(new JacksonDecoder())
                .options(new Request.Options(1000, 3500))
                .retryer(new Retryer.Default(5000, 5000, 3));        return builder;
    }    public List<String> scan(String path){
        ScanResult result = new FastClasspathScanner(path).matchClassesWithAnnotation(FeignApi.class, (Class<?> aClass) -> {
        }).scan();        if(result!=null){            return result.getNamesOfAllInterfaceClasses();
        }        return  null;
    }
}

复制代码

调用接口编写示例:

复制代码

import com.xiaokong.core.base.Result;import com.xiaokong.domain.DO.DeptRoom;import feign.Headers;import feign.Param;import feign.RequestLine;import com.xiaokong.register.FeignApi;import java.util.List;

@FeignApi(serviceUrl = "http://localhost:8085")public interface RoomApi {
    @Headers({"Content-Type: application/json","Accept: application/json"})
    @RequestLine("GET /room/selectById?id={id}")
    Result<DeptRoom> selectById(@Param(value="id") String id);

    @Headers({"Content-Type: application/json","Accept: application/json"})
    @RequestLine("GET /room/test")
    Result<List<DeptRoom>> selectList();
}

复制代码

接口使用示例:

复制代码

@Servicepublic class ServiceImpl{    //将接口注入要使用的bean中直接调用即可    @Autowired    private RoomApi roomApi;
    

    @Test    public void demo(){
        Result<DeptRoom> result = roomApi.selectById("1");
        System.out.println(result);
    }
}

复制代码

 

注意事项:

1.如果接口返回的是一个复杂的嵌套对象,那么一定要明确的指定泛型,因为Feign在解析复杂对象的时候,需要通过反射获取接口返回对象内部的泛型类型才能正确使用Jackson解析。

如果不明确的指明类型,Jackson会将json对象转换成一个LinkedHashMap类型。

2.如果你使用的是的Spring,又需要通过http调用别人的接口,都可以使用这个工具来简化调用与解析的操作。

原文出处

點擊查看更多內容
TA 點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優質文章

正在加載中
  • 推薦
  • 評論
  • 收藏
  • 共同學習,寫下你的評論
感謝您的支持,我會繼續努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進行掃碼打賞哦
今天注冊有機會得

100積分直接送

付費專欄免費學

大額優惠券免費領

立即參與 放棄機會
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號

舉報

0/150
提交
取消