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

来源:互联网 发布:惠普扫描软件 编辑:程序博客网 时间:2024/06/07 04:46

 本文节选自《疯狂Spring Cloud微服务架构实战》

Spring Cloud教学视频:http://blog.csdn.net/boxiong86/article/details/78399104

Feign第三方注解与注解翻译器

使用第三方注解

根据前面章节可知,通过注解修改的接口方法,可以让接口方法获得访问服务的能力。除了Feign自带的方法外,还可以使用第三方的注解。如果想使用JAXRS规范的注解,可以使用Feign的“feign-jaxrs”模块,在pom.xml中加入以下依赖即可:

<!-- FeignJAXRS的支持-->

<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 {

 

//定义urlmethod属性

String url();

String method();

}

 

public interface HelloClient {

@MyUrl(method = "GET", url = "/hello")

String myHello();

}

接下来,就要将MyRrl注解的作用告诉Feign,新建Contract继承BaseContract类,实现请见代码清单5-16

代码清单5-16codes\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方法中,通过MethodgetAnnotation获取MyUrl的实例,将MyUrlurlmethod属性分别设置到Feign的模板中。在创建客户端时,再调用contract方法即可,请见代码清单5-17

代码清单5-17codes\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中,也实现了SpringContract,可以在接口中使用@RequestMapping注解,读者在学习Spring Cloud整合Feign时,见到使用@RequestMapping修饰的接口,就可以明白其中的原理。

 

 本文节选自《疯狂Spring Cloud微服务架构实战》

Spring Cloud教学视频:http://blog.csdn.net/boxiong86/article/details/78399104

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

阅读全文
0 0
原创粉丝点击