leo804188876 2021-11-12 20:43 采纳率: 0%
浏览 138

feign-core 如何读取配置文件中的url, 想实现 springcloud 中 feign在@FeignClient(url="${url}") 这种效果

首先使用的不是 springCloud的feign。
主要是想实现 springcloud 中 feign在@FeignClient(url="${cmdb.url}") 这种占位符的效果

下面是引入的依赖


<dependency>
            <groupId>com.netflix.feign</groupId>
            <artifactId>feign-core</artifactId>
            <version>8.18.0</version>
        </dependency>

application.properties

cmdb.url=http://localhost:8005

@Component
public class CmdbFeignClient implements BeanFactoryPostProcessor {

    //扫描的接口路径
    private String  scanPath="com.example.java.*";
    
    public static Long OPTIONS_CONNECTTIMEOUTMILLIS  = 120000L;
    
    public static Long OPTIONS_READTIMEOUTMILLIS = 120000L;
    
    public static String  REQUEST_HEADER_REMOTE_TOKEN = "Authorization";

    public static String TOKEN_PREFIX = "Bearer ";
    
    public static String  CONTENT_TYPE = "Content-Type";

    private ConfigurableListableBeanFactory beanFactory;

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

         Set<String> classes = PackageTools.findPackageClass(scanPath);
            if(classes==null){
                return ;
            }
            Feign.Builder builder = getFeignBuilder();
            //动态创建bean,并注入到Spring容器中
            if(classes.size()>0){
                for (String claz : classes) {
                    Class<?> targetClass = null;
                    try {
                        targetClass = Class.forName(claz);
                        CmdbFeignApi api = targetClass.getAnnotation(CmdbFeignApi.class);
                        if(api==null){
                            continue;
                        }
// 这里是可以读取每一个申明接口的地址, 但是这个地址只能写死,不能从配置文件中读取,  现在的问题就是想从配置文件中读取
                        String url=api.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(),e);
                    }
                }
            }

            this.beanFactory =beanFactory;

    }

    public Feign.Builder getFeignBuilder(){
        Feign.Builder builder = Feign.builder()
                //使用Jackson进行参数处理,如果有必要可以自行定义
                .encoder(new JacksonEncoder())
                .decoder(new JacksonDecoder())
                //超时处理
                .options(new Request.Options(OPTIONS_CONNECTTIMEOUTMILLIS.intValue(), OPTIONS_READTIMEOUTMILLIS.intValue()))
                .retryer(new Retryer.Default(5000, 5000, 3))
                //每次请求时,自定义内部请求头部信息,例如:权限相关的信息
                .requestInterceptor(template -> {
                    //请求的不是获取token接口,向请求头部里设置token
                    if(!template.url().contains(CmdbTokenApi.tokenUrl)){
                        CmdbTokenService tokenService = this.beanFactory.getBean(CmdbTokenService.class);
                        template.header(REQUEST_HEADER_REMOTE_TOKEN, TOKEN_PREFIX + tokenService.getToken());
                    }else {
                        //请求获取token接口,向请求头部里设置key
                    }
                  template.header(CONTENT_TYPE,"application/json");
                  
                });//.client(new Client.Default(TrustingSSLSocketFactory.get(), new NoopHostnameVerifier()));
        return builder;
    }
}

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

}



// 这里如果是springcloud 的 feign,直接可以使用 ${cmdb.url}就可以使用配置文件中的url, 
// 但是 feign-core是不可以的, 这里是希望能实现如springcloud 的feign一样的使用占位符方式,有没有大佬来解一下。
@CmdbFeignApi(serviceUrl="localhost:8002")
public interface CmdbTokenApi {

    public static final String tokenUrl = "/v1/api/auth";

    @Headers({"Content-Type: application/json","Accept: application/json"})
    @RequestLine("GET /v1/api/auth?code={code}")
    public AccessTokenModel getAccessToken(@Param("code") String code);

}
  • 写回答

1条回答 默认 最新

  • 三千烦恼丝xzh 2021-11-12 21:56
    关注

    openfeign的话也是通过服务别名实现地址管理的,换个思路其实可以直接用类DNS的思路,使用别名然后配置URL的时候读配置文件替换,如果是容器化部署直接就可以使用DNS别名

    评论

报告相同问题?

问题事件

  • 创建了问题 11月12日

悬赏问题

  • ¥100 求数学坐标画圆以及直线的算法
  • ¥100 c语言,请帮蒟蒻写一个题的范例作参考
  • ¥15 名为“Product”的列已属于此 DataTable
  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 自己瞎改改,结果现在又运行不了了
  • ¥15 链式存储应该如何解决
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站