SpringCloud 远程调用

时间:2022-11-06 20:00:18

SpringCloud 远程调用

目录

1. SpringCloud 

2. Nacos 

3. 远程通信

3.1 创建公共子模块 (nacos_commons)

3.1.1 DTO对象

3.2 父项目引入子项目 (nacos_commons) 打成的jar包 

3.3 父项目指向子项目 (nacos_commons)   为儿子

3.4 子项目 (nacos_provider) 

3.5 子项目 (nacos_consumer) 

3.6 启动项目测试进行远程调用服务


前言

 熟悉SpringCloud请阅读下篇文章

 SpringCloud 使用与Nacos_JoneClassMate的博客-CSDN博客 


 1. SpringCloud 

SpringCloud 远程调用

2. Nacos 

SpringCloud 远程调用 

3. 远程通信

  • 就是在互不相干的模块里调用其他模块的接口 

  • 本章内容父项目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.jmh</groupId>
  <artifactId>springcloud01</artifactId>
  <version>1.0-SNAPSHOT</version>
  <!--pom代表这个是个父工程-->
  <packaging>pom</packaging>

  <!--指向儿子-->
  <modules>
    <module>nacos_provider</module>
    <module>nacos_consumer</module>
    <module>nacos_commons</module>
  </modules>

  <name>springcloud01 Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <!--提供版本-->
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
    <spring-boot.version>2.4.1</spring-boot.version>
    <spring-cloud.version>2020.0.0</spring-cloud.version>
    <spring-cloud-alibaba.version>2021.1</spring-cloud-alibaba.version>
  </properties>

  <!--提供依赖-->
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--注册与发现-->
    <dependency>
      <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    </dependency>
    <!--远程通信-->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <!--负载均衡-->
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-loadbalancer</artifactId>
    </dependency>
    <!--对象赋值依赖-->
    <dependency>
      <groupId>ma.glasnost.orika</groupId>
      <artifactId>orika-core</artifactId>
      <version>1.4.6</version>
    </dependency>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
    </dependency>
    <!--子模块nacos_commons依赖-->
    <dependency>
      <groupId>com.jmh</groupId>
      <artifactId>nacos_commons</artifactId>
      <version>0.0.1-SNAPSHOT</version>
    </dependency>
  </dependencies>

  <!--提供依赖版本-->
  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>${spring-boot.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <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>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-alibaba-dependencies</artifactId>
        <version>${spring-cloud-alibaba.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>


</project>

 3.1 创建公共子模块 (nacos_commons)

        3.1.1 DTO对象

  • VO(View Object):视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据 封装起来。
  • DTO(Data Transfer Object):数据传输对象,这个概念来源于J2EE的设计模式,原来的目的是 为了EJB的分布式应用提供粗粒度的数据实体,以减少分布式调用的次数,从而提高分布式调用的 性能和降低网络负载,但在这里,我泛指用于展示层与服务层之间的数据传输对象。
  • DO(Domain Object):领域对象,就是从现实世界中抽象出来的有形或无形的业务实体。
  • PO(Persistent Object):持久化对象,它跟持久层(通常是关系型数据库)的数据结构形成一 一对应的映射关系,如果持久层是关系型数据库,那么,数据表中的每个字段(或若干个)就对应 PO的一个(或若干个)属性。 

SpringCloud 远程调用 

消费者 远程调用 生产者 : 需要网络传输,使用DTO同一封装对象 

原理与SpringBoot启动类相同

  1.将DTO对象封装到公共DTO模块

  2.为需要的项目引入公共DTO模块

注意点

1.不需要继承父模块(重复引用问题)

2.打包方式为jar

3.不需要添加启动类的编译

SpringCloud 远程调用 

  • 创建UserDto对象
package com.jmh.nacos_commons.dto;

import lombok.Data;

/**
 * @author 蒋明辉
 * @data 2022/11/4 17:28
 */
@Data
public class UserDto {
    //账号
    private String names;
    //密码
    private String pwd;
    //秘钥
    private String token;
}

  •  打包 点击要打包的项目右键点击Run Maven 选择Install

SpringCloud 远程调用 

 3.2 父项目引入子项目 (nacos_commons) 打成的jar包 

<!--子模块nacos_commons依赖-->
    <dependency>
      <groupId>com.jmh</groupId>
      <artifactId>nacos_commons</artifactId>
      <version>0.0.1-SNAPSHOT</version>
    </dependency>

 3.3 父项目指向子项目 (nacos_commons)   为儿子

  •  注意!子项目不需要继承父模块(重复引用问题)
<modules>
    <module>nacos_commons</module>
  </modules>

 3.4 子项目 (nacos_provider) 

 Orika 

 Orika是java Bean映射框架,可以实现从一个对象递归拷贝数据至另一个对象。

  • pojo模块 
package com.jmh.nacos_provider.pojo;

import lombok.Data;

/**
 * @author 蒋明辉
 * @data 2022/11/4 17:28
 */
@Data
public class User {
    //账号
    private String name;
    //密码
    private String pwd;
}
  • 启动类配置 
package com.jmh.nacos_provider;

import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;

@SpringBootApplication
@EnableDiscoveryClient
@SuppressWarnings("all")
public class NacosProviderApplication {

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

    @Bean
    /*单例模式:原型链*/
    @Scope("prototype")
    public MapperFactory mapperFactory() {
        return new DefaultMapperFactory.Builder().build();
    }

}
  •  controller模块
package com.jmh.nacos_provider.controller;

import com.jmh.nacos_commons.dto.UserDto;
import com.jmh.nacos_provider.pojo.User;
import ma.glasnost.orika.MapperFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

/**
 * @author 蒋明辉
 * @data 2022/11/4 17:29
 */
@RestController
@RequestMapping("/user")
@SuppressWarnings("all")
public class UserController {

    @Autowired
    private MapperFactory factory;

    @RequestMapping("/{name}")
    public String getByPath(@PathVariable("name") String name){
        System.out.println("name=" + name);
        return "我是生产者: yes";
    }

    @RequestMapping("/param")
    public String getByParam(@RequestParam("name") String name,@RequestParam("pwd") String pwd){
        System.out.println("name=" + name);
        System.out.println("pwd=" + pwd);
        return "我是生产者: yes";
    }

    @RequestMapping("/pojo")
    public String getByPojo(@RequestBody UserDto userDto){
        //属性值一样
        //User u = factory.getMapperFacade().map(userDto, User.class);
        //属性值那不一样
        factory.classMap(UserDto.class, User.class)
                .field("names", "name")
                .byDefault().register();
        User u = factory.getMapperFacade().map(userDto, User.class);
        System.out.println("user=" + u);
        return "我是生产者: yes";
    }

    @RequestMapping("/map")
    public String getByMap(@RequestBody Map<String,Object> map){
        System.out.println("map=" + map);
        return "我是生产者: yes";
    }



}

 3.5 子项目 (nacos_consumer) 

现在为什么来了 现在我在互不相干的模块中怎么去调用呢?用什么方法去调用呢? 生产者提供接口:可以使用以下几个注解接收远程调用的参数值:

  • @PathVariable
  • @RequestParam
  • @RequestBody
  • @RestController
  • 启动类配置 
package com.jmh.nacos_consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@SuppressWarnings("all")
public class NacosConsumerApplication {

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

}
  •  编写远程访问接口
package com.jmh.nacos_consumer.service;

import com.jmh.nacos_commons.dto.UserDto;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

/**
 * @author 蒋明辉
 * @data 2022/11/4 17:29
 */
@FeignClient("nacos-provider")
@SuppressWarnings("all")
public interface IFeignUserService {

    @RequestMapping("/user/{name}")
    String getByPath(@PathVariable("name") String name);

    @RequestMapping("/user/param")
    String getByParam(@RequestParam("name") String name,@RequestParam("pwd") String pwd);

    @RequestMapping("/user/pojo")
    String getByPojo(@RequestBody UserDto user);

    @RequestMapping("/user/map")
    String getByMap(@RequestBody Map<String,Object> map);



}
  •  controller模块
package com.jmh.nacos_consumer.controller;

import com.jmh.nacos_commons.dto.UserDto;
import com.jmh.nacos_consumer.service.IFeignUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

/**
 * @author 蒋明辉
 * @data 2022/11/4 18:27
 */
@RestController
@RequestMapping("/user")
@SuppressWarnings("all")
public class UserController {

    @Autowired
    private IFeignUserService service;

    @RequestMapping("/{name}")
    public String test01(@PathVariable("name") String name){
        service.getByPath(name);
        return "我是消费者: yes";
    }

    @RequestMapping("/test02")
    public String test02(String name,String pwd){
        service.getByParam(name,pwd);
        return "我是消费者: yes";
    }

    @RequestMapping("/test03")
    public String test03(@RequestBody UserDto user){
        service.getByPojo(user);
        return "我是消费者: yes";
    }

    @RequestMapping("/test04")
    public String test04(@RequestBody Map map){
        service.getByMap(map);
        return "我是消费者: yes";
    }

    @RequestMapping("/test05")
    public String test05(String name){
        service.getByPath(name);
        return "我是消费者: yes";
    }


}

 3.6 启动项目测试进行远程调用服务

     1.  测试子项目nacos_consumer test01接口

SpringCloud 远程调用

  • 控制台打印 

SpringCloud 远程调用

     2.  测试子项目nacos_consumer test02接口 

SpringCloud 远程调用

  •  控制台打印

SpringCloud 远程调用

    3.  测试子项目nacos_consumer test03接口 

SpringCloud 远程调用

  • 控制台打印 

SpringCloud 远程调用 

   4.  测试子项目nacos_consumer test04接口   

SpringCloud 远程调用 

  • 控制台打印 

SpringCloud 远程调用 

    5.  测试子项目nacos_consumer test04接口   

SpringCloud 远程调用 

  •  控制台打印

SpringCloud 远程调用