java项目里配置feign,两种使用方式

我自己用的依赖如下:

		<dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-core</artifactId>
            <version>11.0</version>
        </dependency>

        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-jackson</artifactId>
            <version>11.0</version>
        </dependency>
		<dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-httpclient</artifactId>
            <version>11.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>io.github.openfeign</groupId>
            <artifactId>feign-okhttp</artifactId>
            <version>11.0</version>
        </dependency>

有两种使用方式,但是不管哪种方式,都需要在启动类上加上注解@EnableFeignClients
先说我最常用的配置:

@Configuration
@Slf4j
public class CustomFeignBuilder {

    @Bean(name = "custom")
    public Feign.Builder getFeignBuilder() {
        return Feign.builder()
                .logLevel(Level.NONE)
                .encoder(new JacksonEncoder())
                .decoder(new JacksonDecoder())
                .logger(new ErrorLogger())
                .errorDecoder(errorDecoder())
                .retryer(retryer())
                .options(getOptions())
                .requestInterceptor(new FeignHeaderInterceptor())
                .client(apacheHttpClient());
    }
    @Bean
    public Retryer retryer() {
        return Retryer.NEVER_RETRY;
    }

    @Bean
    public FeignErrorDecoder errorDecoder() {
        return new FeignErrorDecoder();
    }

    @Bean
    public Request.Options getOptions() {
        return new Request.Options(2, TimeUnit.SECONDS, 2, TimeUnit.SECONDS, true);
    }

    @Bean
    public ApacheHttpClient apacheHttpClient(){
        log.info("init feign httpclient configuration " );
        // 生成默认请求配置
        RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();
        // 超时时间
        requestConfigBuilder.setSocketTimeout(1000);
        // 连接时间
        requestConfigBuilder.setConnectTimeout(1000);

        // 连接池获取的 超时时间
        requestConfigBuilder.setConnectionRequestTimeout(1000);


        RequestConfig defaultRequestConfig = requestConfigBuilder.build();
        // 连接池配置
        // 长连接保持30秒
        final PoolingHttpClientConnectionManager pollingConnectionManager = new PoolingHttpClientConnectionManager(30, TimeUnit.MILLISECONDS);
        // 总连接数
        pollingConnectionManager.setMaxTotal(5000);
        // 同路由的并发数
        pollingConnectionManager.setDefaultMaxPerRoute(1000);


        // httpclient 配置
        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
        // 保持长连接配置,需要在头添加Keep-Alive
        httpClientBuilder.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy());
        httpClientBuilder.setConnectionManager(pollingConnectionManager);
        httpClientBuilder.setDefaultRequestConfig(defaultRequestConfig);
        CloseableHttpClient client = httpClientBuilder.build();

        // 启动定时器,定时回收过期的连接
        ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                log.debug("=====closeIdleConnections===");
                pollingConnectionManager.closeExpiredConnections();
                pollingConnectionManager.closeIdleConnections(5, TimeUnit.SECONDS);
            }
        }, 10 * 1000, 5 * 1000, TimeUnit.MILLISECONDS);
        log.info("===== Apache httpclient 初始化连接池===");

        return new ApacheHttpClient(client);
    }
}

我使用的是apacheHttpClient,在调用时,先创建工厂,再生成client:

@Configuration
public class FeignFactory {
    @Value("${user-center.url}")
    private String UC_URL;
	//可以定义多个feignBuilder配置不同的拦截器
    @Resource(name = "commentFeign")
    private Feign.Builder commentFeignBuilder;
    @Resource(name = "custom")
    private Feign.Builder feignBuilder;

    @Bean("ucClient")
    public UcClient getUcClient(){
        return commentFeignBuilder.target(UcClient.class,UC_URL);
    }
}

创建client,调用具体接口:

public interface UcClient {

    @RequestLine("GET /*")
    JSONObject batchUser(@QueryMap Map<String,Object> params);

    @RequestLine("POST /**")
    @Headers({"Content-Type: application/json", "Accept: application/json"})
    JSONObject batchUserPost(@RequestBody Map<String,Object> params);
}

还有一种使用方式:

@Configuration
public class FeignConfig {
    @Bean
    public Request.Options options() {
        Request.Options options = new Request.Options(
                5000, 15000
        );
        return options;
    }

    @Bean
    public Retryer retryer() {
        return new Retryer.Default(100, SECONDS.toMillis(1), 2);
    }

    @Autowired
    private ObjectFactory<HttpMessageConverters> messageConverters;

    /**
     * new一个form编码器,实现支持form表单提交
     */
    @Bean
    public Encoder feignFormEncoder() {
        return new SpringFormEncoder(new SpringEncoder(messageConverters));
    }


    /**
     * 开启Feign的日志
     */
    @Bean
    public Logger.Level logger() {
        return Logger.Level.FULL;
    }

}

不需要创建工厂,直接写调用接口:

@FeignClient(name = "baidu-applet-client", url = "${applet.baidu.sohu.url}", configuration = FeignConfig.class)
public interface BaiduAppletClient {

    /**
     * 获取token
     * @param grantType
     * @param clientId
     * @param clientSecret
     * @param scope
     * @return
     */
    @GetMapping(value = "/*")
    BaiduTokenResponseDTO getToken(@RequestParam(value = "grant_type") String grantType,
                                   @RequestParam(value = "client_id") String clientId,
                                   @RequestParam(value = "client_secret") String clientSecret,
                                   @RequestParam(value = "scope") String scope);

}

两种方法都可以~~

你可能感兴趣的:(日常工作问题,java,web开发,java,开发语言,feign)