spring cloud (二) ——feign

1、feign的基本概念 

feign是springcloud中的一个组件,开源组件是openFeign

Feign是声明式的rest客户端。 它使编写Web服务客户端更加容易。 

它具有可插入注释支持,包括Feign注释和JAX-RS注释。 Feign还支持可插拔编码器和解码器

fiegn是一个伪rpc调用,它可以写成dubbo接口形式的远程调用,但本质上还是一个基于http协议

2、feign的基本使用

在没有使用feign之前,只用ribbon做负载均衡时,我们使用RestTemplate或其他模板去发送http请求,

例如这样:在之前需要声明一个restTemplate对象

@GetMapping("/user/{userId}")
    public String getOrderByUser(@PathVariable("userId")  Long userId){
        return  restTemplate.getForObject("http://orderservice/order/list",String.class);

   }

具体案例参考spring cloud (一) ——ribbon

这样写的话会有些繁琐,我们使用feign来简化调用。

首次创建一个父子工程,方便查看和管理

 父工程pom文件:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.atyoung.feign</groupId>
    <artifactId>feigndemo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>user-service</module>
        <module>order-service</module>
        <module>api-service</module>
    </modules>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <spring-cloud.version>Hoxton.SR6</spring-cloud.version>
        <spring-boot.version>2.3.0.RELEASE</spring-boot.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>
pom.xml

 三个子工程:

api-service:远程接口服务

order-service:服务者

user-service:消费者

1、user-service:

application.properties文件:

#指定服务名称
spring.application.name=user-service
#指定服务端口号 server.port=8088 # 配置指定服务的提供者的地址列表,
order-service是服务名字,后面指定集群,地址用逗号隔开
order-service.ribbon.listOfServers= localhost:15000

pom文件:主要有三个依赖,api-service是共同依赖,需要引入,另外就是ribbon和openfeign(已经集成了ribbon)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.atyoung.feign</groupId>
        <artifactId>feigndemo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>com.atyoung.feign</groupId>
    <artifactId>user-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>user-service</name>
    <description>Demo project for Spring Boot</description>


    <dependencies>
        <dependency>
            <groupId>com.atyoung.feign</groupId>
            <artifactId>api-service</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
pom.xml

controller:

@RestController
public class UserController {
      //远程服务接口,是一个代理类,这是由api-service提供
        @Autowired
        IOrderServiceFeignClient orderServiceFeignClient;

        @GetMapping("/user")
        public String list(){
            return orderServiceFeignClient.list();
        }
}

启动类:我们需要加上

EnableFeignClients注解,后面的basePackages 是远程服务所在的包,这是是IOrderServiceFeignClient所在的包,
在api-service下
@EnableFeignClients(basePackages = "com.atyoung.feign.apiservice.feignclient")
@SpringBootApplication
public class UserServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }

}

2、order-service:

application.properties文件:

spring.application.name=order-service
server.port=15000

pom.xml:主要有api-service依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.atyoung.feign</groupId>
        <artifactId>feigndemo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>com.atyoung.fiegn</groupId>
    <artifactId>order-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>order-service</name>
    <description>Demo project for Spring Boot</description>

    <dependencies>
        <dependency>
            <groupId>com.atyoung.feign</groupId>
            <artifactId>api-service</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
View Code

目录结构和平时的分层一样,controller,service,mapper

controller:

@RestController
public class OrderController {

    @Autowired
    private IorderService iorderService;

    @GetMapping("/order/list")
    public String list() {
        return iorderService.list();
    }
}

service:

IorderService
public interface IorderService {

    String list();

}
imp:
@Service
public class OrderImp implements IorderService {
@Override
public String list() {
return "返回订单列表"+ LocalDateTime.now();
}
}

3、api-service:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.atyoung.feign</groupId>
        <artifactId>feigndemo</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <groupId>com.atyoung.feign</groupId>
    <artifactId>api-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>api-service</name>
    <description>Demo project for Spring Boot</description>



    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-openfeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
pom.xml

目录结构:

服务接口:

@FeignClient指定需要调用服务的名字
@FeignClient("order-service")
public interface IOrderServiceFeignClient {

    @GetMapping("/order/list")
    String list();

}

注意点:1、首先需要将api-service进行maven的install,将该依赖到user-service和order-service包中

    2、user-service的启动类的扫描包的路径需要和api-service中的一样

3、调用

浏览器输入:http://localhost:8088/user,就可以访问order-service的服务,最后返回

返回订单列表 + 当前时间

我们还可以使用ribbon进行负载均衡

4、feign的原理

原文地址:https://www.cnblogs.com/tdyang/p/13294156.html