Feign接口单独设置代理访问地址

问题描述

如何给Feign接口单独设置一个代理访问地址

一般微服务之间的通信采用Feign,Feign的声明式调用也是很方便,当然Feign底层也是封装了Http调用,http客户端可选,这里选择的是OkHttp作为调用方式,OkHttp的优势就不多说了,这里主要讨论如何给Feign接口设置代理访问地址。

有些时候我们需要通过代理的方式请求某个地址,可能因为网络之间无法直接通信,需要通过代理方式,这里就需要给http调用设置一个代理调用地址。因为上面选择OkHttp作为底层访问的http客户端,所以只需要给OkHttp设置一个代理地址即可。

那么既然给OkHttp设置一个代理地址,不是可以自定义配置在全局设置即可吗?当然这是可以的,也最方便,但是如果项目里面有很多Feign接口只有部分接口需要单独设置代理访问,这时候就需要单独撸代码了,话不多说直接上代码。

package com.zhoule.demoactuator.service;

import com.zhoule.demoactuator.feign.RemoteFeignService;
import okhttp3.OkHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.util.ReflectionUtils;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.Iterator;
import java.util.Map;

@Service
public class OrderService implements InitializingBean {

    private static final Logger logger = LoggerFactory.getLogger(OrderService.class);

    //远程调用的一个feign客户端
    @Resource
    private RemoteFeignService remoteFeignService;

    @Resource
    private ApplicationContext applicationContext;

    @Override
    public void afterPropertiesSet() throws Exception {
        //获取创建OkhttpClient的Builder对象
        OkHttpClient.Builder builder = applicationContext.getBean(OkHttpClient.Builder.class);
        //设置代理地址
        builder.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 9090)));
        //创建一个新的okhttp client
        okhttp3.OkHttpClient newClient = builder.build();
        //创建一个feign client
        feign.okhttp.OkHttpClient feignClient = new feign.okhttp.OkHttpClient(newClient);
        //获取代理接口的实际处理对象
        InvocationHandler handler = java.lang.reflect.Proxy.getInvocationHandler(remoteFeignService);

        Field dispatchField = ReflectionUtils.findField(handler.getClass(), "dispatch");
        ReflectionUtils.makeAccessible(dispatchField);
        Map<Object, Object> methodMap = (Map<Object, Object>) ReflectionUtils.getField(dispatchField, handler);
        //遍历feign接口里面的每个方法
        Iterator<Map.Entry<Object, Object>> iterator = methodMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<Object, Object> next = iterator.next();
            Object value = next.getValue();

            Field clientField = ReflectionUtils.findField(value.getClass(), "client");
            ReflectionUtils.makeAccessible(clientField);
            //需要直接替换Client而不是Client中的delegate,否则改的还是一个对象
            //Object okHttpClient = ReflectionUtils.getField(clientField, value);

            //Field delegateField = ReflectionUtils.findField(okHttpClient.getClass(), "delegate");
            //ReflectionUtils.makeAccessible(delegateField);

            //设置新的对象
            ReflectionUtils.setField(clientField, value, feignClient);
        }
        logger.info("代理对象初始化完毕");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值