截至目前,还剩eureka client和openfeign两个工程没有整合,但这两个工程本来就应该是一个工程

想一想,eureka client作为微服务的客户端,是真正的微服务业务处理模块;而openfeign工程作为服务间调用的例子,本就应该应用在微服务模块上,所以本章的内容不是单纯移植,而是创建两个服务模块service1和service2实现模块间调用。

理论上所有的业务模块应该有大量通用的依赖,所以可以再建立一层子模块关系,如下图所示,在工程下创建microservices模块,在microservices模块下创建service1和service2模块。

Spring Cloud 5.4: 将多工程整合成多模块工程-eureka client + openfeign二合一_gradle

microservices build.gradle

subprojects {
    dependencies {
        // --- Spring boot dependencies ---
        implementation 'org.springframework.boot:spring-boot-starter-web'

        implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
        implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'

        // --- Other dependencies ---
        // 要想使用lombok,两个依赖必须同时存在
        annotationProcessor 'org.projectlombok:lombok'
        compileOnly 'org.projectlombok:lombok'

    }
}

service1 build.gradle

version = '0.0.1-SNAPSHOT'

service2 build.gradle

version = '0.0.1-SNAPSHOT'

service1 application.yml

server:
  port: 9101
spring:
  application:
    name: service1
eureka:
  client:
    serviceUrl:
      defaultZone: http://admin:123456@localhost:9000/eureka/

service2 application.yml

server:
  port: 9102
spring:
  application:
    name: service2
eureka:
  client:
    serviceUrl:
      defaultZone: http://admin:123456@localhost:9000/eureka/

Service1Application

package com.hao1st.service1;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@EnableFeignClients
@SpringBootApplication
public class Service1Application {

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

}

Service2Application

package com.hao1st.service2;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@EnableFeignClients
@SpringBootApplication
public class Service2Application {

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

}

service1 IndexDemoController

package com.hao1st.service1.biz.indexdemo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class IndexDemoController {

    /**
     * 浏览器访问
     * @return
     */
    @GetMapping("/index")
    public String index(){
        return "您访问的是service1的index";
    }

    /**
     * rpc访问
     * @return
     */
    @PostMapping("/pindex")
    public String postIndex() {
        return "您访问的是service1的postIndex";
    }
}

service2 IndexDemoController

package com.hao1st.service2.biz.indexdemo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class IndexDemoController {

    /**
     * 浏览器访问
     * @return
     */
    @GetMapping("/index")
    public String index(){
        return "您访问的是service2的index";
    }

    /**
     * rpc访问
     * @return
     */
    @PostMapping("/pindex")
    public String postIndex() {
        return "您访问的是service2的postIndex";
    }
}

到此,service1和service2的对外api创建完毕。我们可以依次启动eureka、gateway、service1、service2,启动完毕后访问eureka控制面板localhost:9000查看服务注册状态,服务列表中应包含gateway、service1和service2三个服务,如下图:

Spring Cloud 5.4: 将多工程整合成多模块工程-eureka client + openfeign二合一_spring cloud_02

接下来分别测试service1和service是否畅通,访问localhost:9001/SERVICE1/index,localhost:9001/SERVICE2/index两个地址,可以看到如下内容:

Spring Cloud 5.4: 将多工程整合成多模块工程-eureka client + openfeign二合一_gradle_03

Spring Cloud 5.4: 将多工程整合成多模块工程-eureka client + openfeign二合一_spring cloud_04

接下来,编写rpc调用代码,注意,下面所有代码都在service1里。

先看文件结构,如下图,只需新建两个文件,一个用于外部访问的controller,一个用于调用service2的接口。

Spring Cloud 5.4: 将多工程整合成多模块工程-eureka client + openfeign二合一_gradle_05

Service2Rpc

package com.hao1st.service1.rpc;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;

// 指定要调用的模块,value即配置文件中的spring.application.name
@FeignClient(value="service2")
public interface Service2Rpc {

    // api路径
    @PostMapping("/pindex")
    String rpcService2();
}

RpcController

package com.hao1st.service1.biz.rpcdemo.controller;

import com.hao1st.service1.biz.rpcdemo.rpc.Service2Rpc;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/rpc")
public class RpcController {

    @Resource
    private Service2Rpc service2Rpc;

    @GetMapping("/invoke")
    public String rpcService2() {
        // 调用接口访问service2
        return service2Rpc.rpcService2();
    }
}

这样就OK了,访问service1的/rpc/invoke就可以调用到service2的内容,如下图:

Spring Cloud 5.4: 将多工程整合成多模块工程-eureka client + openfeign二合一_gradle_06

同理,service2调用service1也是同样的逻辑。