瘋狂Spring Cloud連載(13)——Feign第三方註解與註解翻譯器

本文節選自《瘋狂Spring Cloud微服務架構實戰》html

京東購買地址:https://item.jd.com/12256011.htmljava

噹噹網購買地址:http://product.dangdang.com/25201393.htmlgit

Spring Cloud教學視頻:https://my.oschina.net/JavaLaw/blog/1552993github

Spring Cloud電子書:https://my.oschina.net/JavaLaw/blog/1570383api

Feign第三方註解與註解翻譯器

使用第三方註解

        根據前面章節可知,經過註解修改的接口方法,可讓接口方法得到訪問服務的能力。除了Feign自帶的方法外,還可使用第三方的註解。若是想使用JAXRS規範的註解,可使用Feign的「feign-jaxrs」模塊,在pom.xml中加入如下依賴便可:架構

<!-- Feign對JAXRS的支持 -->
		<dependency>
			<groupId>io.github.openfeign</groupId>
			<artifactId>feign-jaxrs</artifactId>
			<version>9.5.0</version>
		</dependency>
		<!-- JAXRS -->
		<dependency>
			<groupId>javax.ws.rs</groupId>
			<artifactId>jsr311-api</artifactId>
			<version>1.1.1</version>
		</dependency>

        在使用註解修飾接口時,能夠直接使用@GET、@Path等註解,例如想要使用GET方法調用「/hello」服務,能夠定義如下接口:app

@GET @Path("/hello")
	String rsHello();

        以上修飾接口的,實際上就等價於「@RequestLine("GET /hello")」。爲了讓Feign知道這些註解的做用,須要在建立服務客戶端時,調用contract方法來設置JAXRS註解的解析類,請見如下代碼:ide

RSClient rsClient = Feign.builder()
				.contract(new JAXRSContract())
				.target(RSClient.class, "http://localhost:8080/");

        設置了JAXRSContract類後,Feign就知道如何處理JAXRS的相關注解,下一小節,將講解Feign是如何處理第三方註解的。微服務

Feign解析第三方註解

        根據前一小節可知,設置了JAXRSContract後,Feign就知道如何處理接口中的JAXRS註解。JAXRSContract繼承了BaseContract類,BaseContract類實現了Contract接口,簡單的說,一個Contract就至關於一個翻譯器,Feign自己並不知道這些第三方註解的含義,而經過實現一個翻譯器(Contract)來告訴Feign,這些註解是作什麼的。學習

        爲了讓讀者可以瞭解其中的原理,本小節將使用一個自定義註解,而且翻譯給Feign,讓其去使用。代碼清單5-15爲自定義註解以及客戶端接口的代碼。

        代碼清單5-15:

        codes\05\5.2\feign-use\src\main\java\org\crazyit\feign\contract\MyUrl.java

        codes\05\5.2\feign-use\src\main\java\org\crazyit\feign\contract\HelloClient.java

@Target(METHOD)
@Retention(RUNTIME)
public @interface MyUrl {

	// 定義url與method屬性
	String url();
	String method();
}

public interface HelloClient {
	
	@MyUrl(method = "GET", url = "/hello")
	String myHello();
}

        接下來,就要將MyRrl註解的做用告訴Feign,新建Contract繼承BaseContract類,實現請見代碼清單5-16。

        代碼清單5-16:

        codes\05\5.2\feign-use\src\main\java\org\crazyit\feign\contract\MyContract.java

public class MyContract extends Contract.BaseContract {

	@Override
	protected void processAnnotationOnClass(MethodMetadata data, Class<?> clz) {
		
	}

	/**
	 * 用於處理方法級的註解
	 */
	protected void processAnnotationOnMethod(MethodMetadata data,
			Annotation annotation, Method method) {
		// 是MyUrl註解才進行處理
		if(MyUrl.class.isInstance(annotation)) {
			// 獲取註解的實例
			MyUrl myUrlAnn = method.getAnnotation(MyUrl.class);
			// 獲取配置的HTTP方法
			String httpMethod = myUrlAnn.method();
			// 獲取服務的url
			String url = myUrlAnn.url();
			// 將值設置到模板中
			data.template().method(httpMethod);
			data.template().append(url);
		}
	}

	@Override
	protected boolean processAnnotationsOnParameter(MethodMetadata data,
			Annotation[] annotations, int paramIndex) {
		return false;
	}
}

        在MyContract類中,須要實現三個方法,分別是處理類註解、處理方法註解、處理參數註解的方法,因爲咱們只定了一個方法註解@MyRul,所以實現processAnnotationOnMethod便可。

        在processAnnotationOnMethod方法中,經過Method的getAnnotation獲取MyUrl的實例,將MyUrl的url、method屬性分別設置到Feign的模板中。在建立客戶端時,再調用contract方法便可,請見代碼清單5-17。

        代碼清單5-17:

        codes\05\5.2\feign-use\src\main\java\org\crazyit\feign\contract\ContractTest.java

public class ContractTest {

	public static void main(String[] args) {
		// 獲取服務接口
		HelloClient helloClient = Feign.builder()
				.contract(new MyContract())
				.target(HelloClient.class, "http://localhost:8080/");
		// 請求Hello World接口
		String result = helloClient.myHello();
		System.out.println("    接口響應內容:" + result);
	}
}

        運行代碼清單5-18,可看到控制檯輸出以下:

接口響應內容:Hello World

        由本例可知,一個Contract實際上承擔的是一個翻譯的做用,將第三方(或者自定義)註解的做用告訴Feign。在Spring Cloud中,也實現了Spring的Contract,能夠在接口中使用@RequestMapping註解,讀者在學習Spring Cloud整合Feign時,見到使用@RequestMapping修飾的接口,就能夠明白其中的原理。

        本文節選自《瘋狂Spring Cloud微服務架構實戰》

        Spring Cloud教學視頻:https://my.oschina.net/JavaLaw/blog/1552993

Spring Cloud電子書:https://my.oschina.net/JavaLaw/blog/1570383

本書代碼共享地址:https://gitee.com/yangenxiong/SpringCloud

相關文章
相關標籤/搜索