疯狂Spring Cloud连载(13)———Feign第三方注解与注解翻译器


声明:本文转载自https://my.oschina.net/JavaLaw/blog/1556824,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

        本文节选自《疯狂Spring Cloud微服务架构实战》,本书将于2017年11月出版。

        Spring Cloud教学视频:https://my.oschina.net/JavaLaw/blog/1552993

本书代码共享地址:https://gitee.com/yangenxiong/SpringCloud

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”服务,可以定义以下接口:

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

        以上修饰接口的,实际上就等价于“@RequestLine("GET /hello")”。为了让Feign知道这些注解的作用,需要在创建服务客户端时,调用contract方法来设置JAXRS注解的解析类,请见以下代码:

		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修饰的接口,就可以明白其中的原理。

本文发表于2017年10月26日 20:34
(c)注:本文转载自https://my.oschina.net/JavaLaw/blog/1556824,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2026 讨论 0 喜欢 1

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1