springcloud远程消费

一、SpringCloud搭建 

springcloud架构图:

先建立一个maven父项目然后删除src因为父项目不需要代码

然后导入依赖

代码:

<?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>org.smy</groupId>
    <artifactId>cloud_02</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>provider</module>
        <module>consumer </module>
    </modules>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</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.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
<!--        远程通信-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>3.0.0</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>

搭建子项目

1.新建生产者provider

新建一个yml文件

application.yml

spring:
  application:
    name: nacos-provider
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
server:
  port: 8081

修改pom.xml

子项目继承父项目

    <parent>
        <artifactId>cloud_02</artifactId>
        <groupId>org.smy</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

启动类添加注解

@EnableDiscoveryClient

 2.新建消费者consumer

添加application.yml文件

spring:
  application:
    name: nacos-consumer
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
server:
  port: 8082

修改pom.xml

子项目继承父项目

<parent>
    <artifactId>cloud_02</artifactId>
    <groupId>org.smy</groupId>
    <version>1.0-SNAPSHOT</version>
</parent>

然后也在启动类添加一样的注解

调用方法

①、provider生产者编写生产鸡腿方法·

新建controller软件包,新建ProviderController

package com.provider.code.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProviedrController {

    @RequestMapping("/run")
    public String run(){
     return "鸡腿";
    }

}

、消费者编写获得鸡腿方法 (跨服务器访问

(1)pom.xml中增加依赖(负载均衡)

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

启动类添加注解

启动类增加域名访问对象

@LoadBalanced:达到负载均衡的能力
package com.example.code;

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
public class ConsumerApplication {

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

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

}

 新建controller软件包,新建ConsumerController

package com.example.code.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class ConsumerController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping("/run")
    public String run(){
     return restTemplate.getForObject("http://nacos-provider/run",String.class);
    }

}

 二、(消费者生产者)远程调用接口定义

现在的生产者(provider)是没有接收参数的,返回String类型的

所以现在我们要是生产者接收参数

1、生产者(provider)

①、实体类

首先,写一个用户实体类

建立pojo软件包,新建User实体类

package com.provider.code.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
public class User {

    private String account;
    private String password;
}

②、提供接口让别人来操纵用户实体类

使用UserController来构建一些有参数的东西

package com.provider.code.controller;

import com.provider.code.pojo.User;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@RestController
@RequestMapping("/user")
public class UserController {
//远程:
//@PathVariable
//@RequestParam
//@RequestBody


    @RequestMapping("/{account}")
    public String getByPath(@PathVariable String account){
        System.out.println("account"+account);
        return "provider say : yes";
    }

    @RequestMapping("/param")
    public String getByParam (@RequestParam("account") String account,@RequestParam("password") String password){
        System.out.println("account"+account+"password"+password);
        return "provider say : yes";
    }

    @RequestMapping("/pojo")
    public String getByPojo(@RequestBody User user){
        System.out.println("pojo "+user);
        return "provider say : yes";
    }

    @RequestMapping("/more")
    public String getBymore(@RequestBody Map<String,Object> map ){
        System.out.println("more"+map);
        return "provider say : yes";
    }

}

 

 2、消费者(Consumer)

①、新建pojo软件包,新建user(与生产者user一模一样)

package com.example.code.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
public class User {

    private String account;
    private String password;
}

②、新建service软件包,新建FeignUserService接口

使消费者直接调用生产者里面的接口

在消费者里面直接把生产者的接口定义出来

@FeignClient:远程通信
package com.example.code.service;



import com.example.code.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@FeignClient("nacos-provider")
public interface FeignUserService {

//    这个service和生产者的接口保持一致

    @RequestMapping("/user/{account}")
     String getByPath(@PathVariable(value = "account") String account);

    @RequestMapping("/user/param")
     String getByParam (@RequestParam("account") String account,@RequestParam("password") String password);

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

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

}

启动类添加注解

@EnableFeignClients
package com.example.code;

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
public class ConsumerApplication {

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

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

}

只要参数是复杂对象,即使指定了是 GET 方法, feign 依然会以 POST 方法进行发送请求,同时生产者必须支持POST 请求并给参数添加 @RequestBody 注解
④、controller包下新建UserController

消费者调用UserService接口

FeignClient接口,不能使用@GettingMapping之类的组合注解
FeignClient接口中,如果使用到@PathVariable必须指定其value
当使用feign传参数的时候,需要加上@RequestParam注解,否则对方服务无法识别参数
并使用 Feign 表示其需要远程对接的服务名称 , 并使用 @RequestMapping 表示其映射的
路径
 

package com.example.code.controller;

import com.example.code.pojo.User;
import com.example.code.service.FeignUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RestController
@RequestMapping("/user")
public class UserController {

@Autowired
    private FeignUserService service;

@RequestMapping("/test01")
    public String test01(String account){
     service.getByPath(account);
             return "yes";
    }

    @RequestMapping("/{account}")
    public String test02(@PathVariable String account){
        service.getByPath(account);
        return "yes";
    }

    @RequestMapping("/test03")
    public String test03(String account,String password){
        service.getByParam(account,password);
        return "yes";
    }

    @RequestMapping("/test04")
    public String test04(String account,String password){
        service.getByPojo(new User().setAccount(account).setPassword(password));
        return "yes";
    }

    @RequestMapping("/test05")
    public String test05(Map<String,Object> map){
        service.getBymore(map);
        return "yes";
    }

}

 

三、DTO层的构建

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

 

消费者 远程调用 生产者 : 需要网络传输 , 使用 DTO 同一封装对象
原理与 SpringBoot 启动类相同
1. DTO 对象封装到公共 DTO 模块
2. 为需要的项目引入公共 DTO 模块
注意点
1. 不需要继承父模块 ( 重复引用问题 )
2. 打包方式为 jar
3. 不需要添加启动类的编译

新建一个模块 

 

新建dto包

UserDto

package com.cloud02.code.dto;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
public class UserDto {

    private String account;
    private String password;
}

 

 修改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>
    <groupId>com.cloud02</groupId>
    <artifactId>code</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>commons</name>
    <description>Demo project for Spring Boot</description>

<!--    不要继承父项目-->

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.4.1</spring-boot.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </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>
        </dependencies>
    </dependencyManagement>

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

        </plugins>
    </build>

</project>

引用Commons

因为provider和consumer都要引用Commons

①、将Commons导成jar

 在父项目pom.xml

导入

 <dependency>
            <groupId>com.cloud02</groupId>
            <artifactId>code</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

父项目单方面认亲

  <module>commons</module>

将消费者中的pojo包中的实体类删除

导入userdto

假如属性多的话,数据就会很长 所有我们学习Orika框架

 5、Orika(Orika对象复制教程(完美笔记) - 付宗乐 - 博客园

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

在开发多层应用程序中非常有用。在这些层之间交换数据时,通常为了适应不同 API 需要转换一个实例至

另一个实例。

①、生产(provider)导入依赖

 

<dependency>
    <groupId>ma.glasnost.orika</groupId>
    <artifactId>orika-core</artifactId>
    <version>1.4.6</version>
</dependency>

②、生产(provider)的启动类增加方法

@Bean
public MapperFactory mapperFactory(){
   return new DefaultMapperFactory.Builder().build();
}

③、生产者(provider)的UserController类进行注入

将UserDto填到User中去,将dto转成user对象
@Autowired
    private MapperFactory factory;
    @RequestMapping("/pojo")
    public String getByPojo(@RequestBody UserDto dto){
//        dto中的属性可能比实体类多
//        需要拿到的实体类,根据实体类中的属性去数据库查询数据
//         User u=new User();
//         u.setAccount(dto.getAccount()).setPassword(dto.getPassword());

//       在学习Struts2的时候 beanutils(将我的数据与实体类数据匹配,然后将符合的数据放到数据库)


        User u=factory.getMapperFacade().map(dto, User.class);
        System.out.println("pojo "+dto);
        return "provider say : yes";
    }

属性不同:

factory.classMap(UserDto.class, User.class)
        .field("name", "userName")
        .byDefault().register();
User user = factory.getMapperFacade().map(dto, User.class);

 

怕影响到的类的MapperFacade,因此:

单链模式改成原型链模式:

修改启动类:

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值