版本信息
Spring Cloud : Hoxton.SR1
Spring Boot : 2.2.2.RELEASE
Zookeeper : 3.5.6 (注册中心使用)
OpenFeign核心api
Feign is a Java to HTTP client binder inspired by Retrofit, JAXRS-2.0,
and WebSocket
- feign.Feign 核心类
- feign.Contract 服务接口类的注解和值解析
- feign.Client 调用
- feign.Retryer 重试
- feign.codec.Encoder 序列化,对象转成Http请求
- feign.codec.Decoder 反序列化,Http请求转换为对象
- feign.QueryMapEncoder 查询参数的编码
- feign.codec.ErrorDecoder 错误信息编码
- feign.Request 请求参数
- feign.InvocationHandlerFactory 控制反射方法分派
Spring Cloud Feign使用
服务端
一个简单的对外提供服务,基于Zookeeper注册中心
1.添加pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--zookeeper 客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
2.简单的对外提供服务端点
/**
* 演示服务端点
*
* @author FelixFly <chenglinxu@yeah.net>
* @date 2020/2/7
*/
@RestController
public class EchoController {
@Autowired
private Environment environment;
@GetMapping("/echo")
public String echo(@RequestParam String message) {
// 由于采用的是随机端口,这地方必须采用这个方式获取端口
String port = environment.getProperty("local.server.port");
return "ECHO(" + port + "):" + message;
}
}
3.配置文件application.yml
spring:
application:
name: feign-server
cloud:
zookeeper:
connect-string: 127.0.0.1:2181
server:
port: 0
4.服务启动程序类FeignServerApplication
/**
* Feign 服务端应用
*
* @author FelixFly <chenglinxu@yeah.net>
* @date 2020/2/7
*/
@SpringBootApplication
public class FeignServerApplication {
public static void main(String[] args) {
SpringApplication.run(FeignServerApplication.class, args);
}
}
启动服务,根据启动日志查看本地的随机端口,此次端口是60981
http://127.0.0.1:60981/echo?message=Hello 返回信息ECHO(60981):Hello
客户端
1.添加pom依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--zookeeper 客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
</dependency>
<!--openfeign 客户端调用-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.服务提供接口
/**
* 服务提供echo服务
*
* @author FelixFly <chenglinxu@yeah.net>
* @date 2020/2/7
*/
@FeignClient("feign-server") //标注是Feign Client
public interface EchoService {
@GetMapping("/echo")
String echo(@RequestParam("message") String message);
}
3.客户端提供服务端点
/**
* 演示服务端点
*
* @author FelixFly <chenglinxu@yeah.net>
* @date 2020/2/7
*/
@RestController
public class EchoController {
@Autowired
private EchoService echoService;
@GetMapping("/echo")
public String echo(String message) {
return this.echoService.echo(message);
}
}
4.配置文件application.yml
spring:
application:
name: feign-client
cloud:
zookeeper:
connect-string: 127.0.0.1:2181
server:
port: 8090
5.服务启动程序类FeignClientApplication
/**
* Feign 客户端服务
*
* @author FelixFly <chenglinxu@yeah.net>
* @date 2020/2/7
*/
@SpringBootApplication
@EnableFeignClients(clients = EchoService.class) //启用Feign Client
public class FeignClientApplication {
public static void main(String[] args) {
SpringApplication.run(FeignClientApplication.class, args);
}
}
启动服务,http://localhost:8090/echo?message=hello 返回信息ECHO(60981):hello
RestTemplate自定义实现服务调用
自定义客户端调用注解
/**
* rest 客户端调用
*
* @author FelixFly <chenglinxu@yeah.net>
* @date 2020/2/7
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RestFeignClient {
/**
* 服务名称
*
*/
String value() default "";
}
自定义客户端调用服务
/**
* 服务提供echo服务
*
* @author FelixFly <chenglinxu@yeah.net>
* @date 2020/2/7
*/
@RestFeignClient("feign-server") //标注是Feign Client
public interface RestEchoService {
@GetMapping("/echo")
String echo(@RequestParam("message") String message);
}
自定义客户端启用注解
/**
* 启用Rest 客户端
*
* @author FelixFly <chenglinxu@yeah.net>
* @date 2020/2/7
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(RestFeignClientsRegistrar.class)
public @interface EnableRestFeignClients {
/**
* {@link RestFeignClient}接口列表
*/
Class<?>[] clients() default {
};
}
导入RestFeignClientsRegistrar
/**
* rest 客户端注册
*
* @author FelixFly <chenglinxu@yeah.net>
* @date 2020/2/7
*/
public class RestFeignClientsRegistrar
implements ImportBeanDefinitionRegistrar, BeanFactoryAware {
private BeanFactory beanFactory;
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
// 类加载类
ClassLoader classLoader = metadata.getClass().getClassLoader();
// 获取EnableRestFeignClients注解的内容
Map<String, Object> annotationAttributes = metadata
.getAnnotationAttributes(EnableRestFeignClients.class.getName());
// 获取clients
Class<?>[] clients = (Class<?>[]) annotationAttributes.get("clients");
Stream.of(clients)
.filter(Class::isInterface)
.filter(interfaceClass ->
Objects.nonNull(AnnotationUtils.