Spring Boot 2關於http介面呼叫(6)
阿新 • • 發佈:2019-01-07
使用自定義HttpClientProxy
這裡其實是參考FeignClient的功能,實現自己的代理包裝類。因為FeignClient封裝的太好,功能很強大,但是有時候想實現一點特殊的功能,改造起來很麻煩。
定義自己的FeignClient註解
@Target(TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface HttpClientEx { @AliasFor("hostName") String value() default ""; /** * 主機名http://www.baidu.com * * @return */ @AliasFor("value") String hostName() default ""; /** * http請求資料組裝 * * @return */ Class<HttpRequestBuilder> config() default HttpRequestBuilder.class; }
定義自己的RequestMapping註解
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RequestMappingEx { @AliasFor("name") String value() default ""; /** * 介面名a/b/c * * @return */ @AliasFor("value") String name() default ""; /** * 請求方法 * * @return */ HttpMethod method() default HttpMethod.GET; /** * contentType * * @return */ String contentType() default MediaType.APPLICATION_JSON_UTF8_VALUE; /** * 請求頭a=b * * @return */ String[] headers() default {}; /** * 擴充套件引數a=b * * @return */ String[] params() default {}; }
自定義HttpClientProxy,用於解析自定義的兩個註解
public final class HttpClientProxy<T> implements InvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Class clz = method.getDeclaringClass(); if (clz != null) { HttpClientEx typeAnno = (HttpClientEx) (clz.getAnnotation(HttpClientEx.class)); RequestMappingEx methodAnno = method.getAnnotation(RequestMappingEx.class); //...... } return null; } }
自定義HttpClientFactory,通過Proxy構造一個例項
@SuppressWarnings("unchecked")
public static <T> T getBean(Class<T> clz) throws IllegalArgumentException {
return (T) Proxy.newProxyInstance(clz.getClassLoader(), new Class[]{clz}, new HttpClientProxy<T>());
}
定義介面
@HttpClientEx(hostName = "http://localhost:9999")
public interface IHelloService {
@RequestMappingEx(name = "demo/hello", method = HttpMethod.GET, headers = {"xxx=123"})
HttpRspDTO<String> demoHello(@RequestParam(value = "msg") String msg);
@RequestMappingEx(name = "demo/hello", method = HttpMethod.POST, headers = {"xxx=123"})
HttpRspDTO<String> demoHello(@RequestBody Map<String, Object> reqMap);
}
單元測試
@Test
public void test1() {
long begin = System.currentTimeMillis();
IHelloService testService = HttpClientFactory.getBean(IHelloService.class);
long end = System.currentTimeMillis();
System.out.println("*****構造物件消耗時間(秒):" + (end - begin) / 1000.0);
begin = System.currentTimeMillis();
HttpRspDTO<String> rspDTO = testService.demoHello("張三");
end = System.currentTimeMillis();
System.out.println("*****查詢資料消耗時間(秒):" + (end - begin) / 1000.0);
System.out.println(rspDTO);
begin = System.currentTimeMillis();
Map<String, Object> paraMap = new HashMap<String, Object>();
paraMap.put("msg", "這是一條測試資料");
rspDTO = testService.demoHello(paraMap);
end = System.currentTimeMillis();
System.out.println("*****查詢資料消耗時間(秒):" + (end - begin) / 1000.0);
System.out.println(rspDTO);
}