Feigh声明式服务调用

在RPC框架中,服务调用一般是服务的暴露接口,并提供客户端API,客户端在添加依赖后,即可像本地方法一样调用远程服务,SpringCloud也提供了类似需求,而在此之前,使用的是RestTemplate调用,这种调用方式不是很直观

目的

  • 学会使用Feigh声明式服务调用

准备工作

需要4个项目: eureka-server:服务注册中心 user-service-feigh-api:服务API,客户端依赖,user-service-feigh-impl:服务实现放 ,user-service-client:服务消费方

  • 提供一个供服务方和消费方共用的api接口 user-service-feigh-api
  • 提供一个增删改查的用户服务 user-service-feigh-impl
  • 体统一个调用user-srvice的客户端 user-service-client

Eureka服务中心搭建

参考Eureka服务治理

服务提供方

新建项目:

user-service-api

该项目仅仅提供服务API,并不需要启动,服务提供方和服务消费方都依赖该项目,实际情况下,该项目应该写在user-service-feigh-impl中,通过不同的打包方式将该项目打包出来,由各个服务方调用

添加依赖


    org.springframework.cloud
    spring-cloud-starter-feign

提供API

只有接口,没有实现


@FeignClient("USER-SERVICE")
public interface UserService {


    @RequestMapping("add-user")
    String addUser();

    @RequestMapping("list-user")
    List listUser();

    @RequestMapping("delete-user")
    boolean deleteUser();


    @RequestMapping("update-user")
    String updateUser();

}

public class User {

    private int id;
    private String name;
    private int age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

启动

不需要启动,由user-service-feigh-impl和user-service依赖

服务实现方

新建项目:

user-service-feigh-impl

添加依赖


    org.springframework.cloud
    spring-cloud-starter-eureka



    cn.liuyiyou.springcloud
    user-service-feigh-api
    0.0.1-SNAPSHOT

配置文件

#服务命名
spring.application.name=user-service
#指定服务注册中心地址
eureka.client.service-url.defaultZone=http://localhost:1111/eureka
server.port=8080

启动类

@EnableDiscoveryClient
@SpringBootApplication
public class UserServiceFeighApiApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceFeighApiApplication.class, args);
    }
}

服务实现类

注意:

  • 实现了UserService接口,确保声明的服务都有其实现方法
  • 包所在的名字是service,但是写的方式好像是controller,这是因为采用的是http方式进行调用

package cn.liuyiou.cloud.service;
import cn.liuyiou.cloud.model.User;
import com.google.common.collect.Lists;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

/**
 * 该注解必须是  @RestController  不能是@Service
 */
@RestController
public class UserServiceImpl implements UserService {

    
    @Override
    public String addUser() {
        return "add User Has Been Called";
    }

    
    @Override
    public List listUser() {
        return Lists.newArrayList(new User() {{
            setId(1);
            setAge(18);
            setName("lyy");
        }}, new User() {{
            setId(2);
            setAge(18);
            setName("yi");
        }}, new User() {{
            setId(1);
            setAge(18);
            setName("you");
        }});
    }

    
    @Override
    public boolean deleteUser() {
        return true;
    }

    
    @Override
    public String updateUser() {
        return "update User Has Been Called";
    }
}

启动

观察是否注册到服务中心中了

服务调用方

新建项目

user-service-client

添加依赖

因为只是调用方,该依赖可以不添加


    org.springframework.cloud
    spring-cloud-starter-eureka

配置文件

因为只是调用方,该配置可以不添加

#服务命名
spring.application.name=hello-service
#指定服务注册中心地址
eureka.client.service-url.defaultZone=http://localhost:1111/eureka
server.port=10000
#需要启动eureka-server后启动,再看 http://localhost:1111/ 会发现hello-service已经注册到服务中心中去了

添加注释

因为只是调用方,该@EnableDiscoveryClient可以不添加

注意

因为UserService是单独编译一个jar包,所以在使用@EnableFeignClients注解时需要指定basePackages的值,否则报错:
Consider defining a bean of type 'cn.liuyiou.cloud.service.api.Service' in your configuration.

/**
 * 因为UserService是单独编译一个jar包,所以在使用@EnableFeignClients注解时需要指定basePackages的值,否则报错
 * Consider defining a bean of type 'cn.liuyiou.cloud.service.api.Service' in your configuration.
 */
@EnableFeignClients(basePackages = "cn.liuyiou.cloud.service.api")
@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceClientApplication.class, args);
    }
}

调用服务

package cn.liuyiou.cloud.controller;

import cn.liuyiou.cloud.model.User;
import cn.liuyiou.cloud.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.util.List;

@RestController
public class UserController {

    private Logger logger = LoggerFactory.getLogger(UserController.class);


    @Autowired
    private UserService userService;

    public UserController() {
        logger.info("userservice In Construct {}", userService);
    }


    @PostConstruct
    public void printService(){
        logger.info("userservice In PostConstruct::{}", userService);
    }

    @RequestMapping("/add-user")
    public String saveUser() {
        return userService.addUser();
    }

    @RequestMapping("/list-user")
    public List getUser() {
        logger.info("userservice In Method ::{}", userService);
        List userList = userService.listUser();
        return userList;
    }


    @RequestMapping("/edit-user")
    public String editUser() {
        return userService.updateUser();
    }


    @RequestMapping("/delete-user")
    public Boolean deleteUser() {
        return userService.deleteUser();
    }
}


启动

  • userservice In Construct null
  • userservice In PostConstruct::HardCodedTarget(type=UserService, name=USER-SERVICE, url=http://USER-SERVICE)
  • userservice In Method ::HardCodedTarget(type=UserService, name=USER-SERVICE, url=http://USER-SERVICE)

访问 : http://localhost:8081/list-user

[{"id":1,"name":"lyy","age":18},{"id":2,"name":"yi","age":18},{"id":1,"name":"you","age":18}]

API和IMP合二为一

具体的目录规范需要自己定义


    cn.liuyiyou.springcloud
    user-service-api
    0.0.2-SNAPSHOT
    jar
    user-service-api



    
        org.apache.maven.plugins
        maven-jar-plugin
        3.0.2
        
            
                cn/liuyiyou/cloud/model/**/*.class
                cn/liuyiyou/cloud/service/api/**/*.class
            
        
    


客户端依赖修改成 0.0.2

参考资料

Spring Cloud入门教程(三):声明式服务调用(Feign)
Spring Cloud 声明式服务调用 Feign

你可能感兴趣的:(Feigh声明式服务调用)