1. 项目中引入spring-cloud-starter-openfeign
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
1.1 spring-cloud-starter-openfeign 中到底又有什么呢?
下载源码:
下面我们关注的重点在spring-cloud-starter-openfeign,我们代码中引入的也是spring-cloud-starter-openfeign:
下面使用:
mvn dependency:tree
的到如下结果仔细看可以看到他包含的内容,重点在:
spring-cloud-openfeign-core:jar
io.github.openfeign:feign-core:jar:9.7.0:compile
com.netflix.ribbon:ribbon-core:jar
com.netflix.hystrix:hystrix-core:jar
feign-hystrix
feign-okhttp
feign-java8
hystrix-core
等等
建议大家,认真的读一遍,这个树,对其有一个感性的认识:
[INFO] org.springframework.cloud:spring-cloud-starter-openfeign:jar:2.0.5.BUILD-SNAPSHOT
[INFO] +- org.springframework.cloud:spring-cloud-starter:jar:2.0.3.BUILD-SNAPSHOT:compile
[INFO] | +- org.springframework.boot:spring-boot-starter:jar:2.0.8.RELEASE:compile
[INFO] | | +- org.springframework.boot:spring-boot:jar:2.0.8.RELEASE:compile
[INFO] | | | \- org.springframework:spring-context:jar:5.0.12.RELEASE:compile
[INFO] | | | \- org.springframework:spring-expression:jar:5.0.12.RELEASE:compile
[INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:2.0.8.RELEASE:compile
[INFO] | | | +- ch.qos.logback:logback-classic:jar:1.2.3:compile
[INFO] | | | | \- ch.qos.logback:logback-core:jar:1.2.3:compile
[INFO] | | | +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.10.0:compile
[INFO] | | | | \- org.apache.logging.log4j:log4j-api:jar:2.10.0:compile
[INFO] | | | \- org.slf4j:jul-to-slf4j:jar:1.7.25:compile
[INFO] | | +- javax.annotation:javax.annotation-api:jar:1.3.2:compile
[INFO] | | \- org.yaml:snakeyaml:jar:1.19:runtime
[INFO] | +- org.springframework.cloud:spring-cloud-context:jar:2.0.3.BUILD-SNAPSHOT:compile
[INFO] | \- org.springframework.security:spring-security-rsa:jar:1.0.7.RELEASE:compile
[INFO] | \- org.bouncycastle:bcpkix-jdk15on:jar:1.60:compile
[INFO] | \- org.bouncycastle:bcprov-jdk15on:jar:1.60:compile
[INFO] +- org.springframework.cloud:spring-cloud-openfeign-core:jar:2.0.5.BUILD-SNAPSHOT:compile
[INFO] | +- org.springframework.boot:spring-boot-autoconfigure:jar:2.0.8.RELEASE:compile
[INFO] | +- org.springframework.cloud:spring-cloud-netflix-ribbon:jar:2.0.3.BUILD-SNAPSHOT:compile
[INFO] | +- org.springframework.boot:spring-boot-starter-aop:jar:2.0.8.RELEASE:compile
[INFO] | | +- org.springframework:spring-aop:jar:5.0.12.RELEASE:compile
[INFO] | | \- org.aspectj:aspectjweaver:jar:1.8.13:compile
[INFO] | \- io.github.openfeign.form:feign-form-spring:jar:3.3.0:compile
[INFO] | +- io.github.openfeign.form:feign-form:jar:3.3.0:compile
[INFO] | | \- com.google.code.findbugs:annotations:jar:3.0.1:compile
[INFO] | | \- net.jcip:jcip-annotations:jar:1.0:compile
[INFO] | \- commons-fileupload:commons-fileupload:jar:1.3.3:compile
[INFO] | \- commons-io:commons-io:jar:2.2:compile
[INFO] +- org.springframework:spring-web:jar:5.0.12.RELEASE:compile
[INFO] | +- org.springframework:spring-beans:jar:5.0.12.RELEASE:compile
[INFO] | \- org.springframework:spring-core:jar:5.0.12.RELEASE:compile
[INFO] | \- org.springframework:spring-jcl:jar:5.0.12.RELEASE:compile
[INFO] +- org.springframework.cloud:spring-cloud-commons:jar:2.0.3.BUILD-SNAPSHOT:compile
[INFO] | \- org.springframework.security:spring-security-crypto:jar:5.0.11.RELEASE:compile
[INFO] +- io.github.openfeign:feign-core:jar:9.7.0:compile
[INFO] +- io.github.openfeign:feign-slf4j:jar:9.7.0:compile
[INFO] | \- org.slf4j:slf4j-api:jar:1.7.25:compile
[INFO] +- io.github.openfeign:feign-hystrix:jar:9.7.0:compile
[INFO] | +- com.netflix.archaius:archaius-core:jar:0.7.6:compile
[INFO] | | +- com.google.code.findbugs:jsr305:jar:3.0.1:compile
[INFO] | | +- com.google.guava:guava:jar:16.0:runtime
[INFO] | | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.9.0:runtime
[INFO] | | +- com.fasterxml.jackson.core:jackson-core:jar:2.9.8:runtime
[INFO] | | \- com.fasterxml.jackson.core:jackson-databind:jar:2.9.8:runtime
[INFO] | \- com.netflix.hystrix:hystrix-core:jar:1.5.18:compile
[INFO] | \- org.hdrhistogram:HdrHistogram:jar:2.1.9:compile
[INFO] +- io.github.openfeign:feign-java8:jar:9.7.0:compile
[INFO] +- org.springframework.cloud:spring-cloud-starter-netflix-ribbon:jar:2.0.3.BUILD-SNAPSHOT:compile
[INFO] | +- com.netflix.ribbon:ribbon:jar:2.2.5:compile
[INFO] | | +- com.netflix.ribbon:ribbon-transport:jar:2.2.5:runtime
[INFO] | | | +- io.reactivex:rxnetty-contexts:jar:0.4.9:runtime
[INFO] | | | \- io.reactivex:rxnetty-servo:jar:0.4.9:runtime
[INFO] | | +- javax.inject:javax.inject:jar:1:runtime
[INFO] | | \- io.reactivex:rxnetty:jar:0.4.9:runtime
[INFO] | +- com.netflix.ribbon:ribbon-core:jar:2.2.5:compile
[INFO] | | \- commons-lang:commons-lang:jar:2.6:compile
[INFO] | +- com.netflix.ribbon:ribbon-httpclient:jar:2.2.5:compile
[INFO] | | +- commons-collections:commons-collections:jar:3.2.2:runtime
[INFO] | | +- org.apache.httpcomponents:httpclient:jar:4.5.6:runtime
[INFO] | | | +- org.apache.httpcomponents:httpcore:jar:4.4.10:runtime
[INFO] | | | \- commons-codec:commons-codec:jar:1.11:runtime
[INFO] | | +- com.sun.jersey:jersey-client:jar:1.19.1:runtime
[INFO] | | | \- com.sun.jersey:jersey-core:jar:1.19.1:runtime
[INFO] | | | \- javax.ws.rs:jsr311-api:jar:1.1.1:runtime
[INFO] | | +- com.sun.jersey.contribs:jersey-apache-client4:jar:1.19.1:runtime
[INFO] | | +- com.netflix.servo:servo-core:jar:0.12.21:runtime
[INFO] | | \- com.netflix.netflix-commons:netflix-commons-util:jar:0.3.0:runtime
[INFO] | +- com.netflix.ribbon:ribbon-loadbalancer:jar:2.2.5:compile
[INFO] | | \- com.netflix.netflix-commons:netflix-statistics:jar:0.1.1:runtime
[INFO] | \- io.reactivex:rxjava:jar:1.2.0:compile
[INFO] \- org.springframework.cloud:spring-cloud-starter-netflix-archaius:jar:2.0.3.BUILD-SNAPSHOT:compile
[INFO] +- org.springframework.cloud:spring-cloud-netflix-archaius:jar:2.0.3.BUILD-SNAPSHOT:compile
[INFO] \- commons-configuration:commons-configuration:jar:1.8:compile
1.2 OpenFeign的核心是spring的openfeign
源码如下:
scm:git:https://github.com/openfeign/feign.git
feign是一个顶级的抽象类:
package feign;
public abstract class Feign {
public Feign() {
}
/**
* Returns a new instance of an HTTP API, defined by annotations in the {@link Feign Contract},
* for the specified {@code target}. You should cache this result. 此方法在Feign 的实现类ReflectiveFeign.java 反射Feign中有实现。
*/
public abstract <T> T newInstance(Target<T> target);
}
在ReflectiveFeign.java中有个特别重要的内部类
static class FeignInvocationHandler implements InvocationHandler {
... ...
}
这里需要说明,我们在声明式定义@FeignClient,如:
@FeignClient(
value = AppConstant.APPLICATION_RESOURCE_NAME,
fallback = ISmsClientFallback.class
)
时,feign-core会帮我们使用代理的方式生成器实现类。代理的顶级接口就是
package java.lang.reflect;
/**
* {@code InvocationHandler} is the interface implemented by
* the <i>invocation handler</i> of a proxy instance.
*
* <p>Each proxy instance has an associated invocation handler.
* When a method is invoked on a proxy instance, the method
* invocation is encoded and dispatched to the {@code invoke}
* method of its invocation handler.
*
* @author Peter Jones
* @see Proxy
* @since 1.3
*/
public interface InvocationHandler {
这里插一句:对于invocatinHandler的实现有很多。主要关注这两种。如果开启了hystrix的话,就会走HystrixInvocationHandler
从ReflectiveFeign.java(feign.hystrix.HystrixInvocationHandler,由openfeign重写的feign中的子项目core这么项目中) 和 HystrixInvocationHandler.java(在openfeign的子项目hystrix这个项目中,定义为feign-hystrix,)可以看出,这两个类的代码均有spring书写。
使用的是HystrixInvocationHandler.java