zoukankan      html  css  js  c++  java
  • 搭建SpringCloud微服务

    建立spring父模块

    • 删除不必要的src目录
    • 父模块中的pom.xml中添加相应的依赖以及插件、远程仓库地址
     1     <!-- 项目的打包类型, 即项目的发布形式, 默认为 jar. 对于聚合项目的父模块来说, 必须指定为 pom -->
     2     <packaging>pom</packaging>
     3 
     4     <name>spring-cloud-home-page</name>
     5     <description>Project For VastHomepage SpringCloud</description>
     6 
     7     <parent>
     8         <groupId>org.springframework.boot</groupId>
     9         <artifactId>spring-boot-starter-parent</artifactId>
    10         <version>2.1.4.RELEASE</version>
    11     </parent>
    12 
    13     <properties>
    14         <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
    15     </properties>
    16 
    17     <dependencies>
    18         <!-- lombok 工具通过在代码编译时期动态的将注解替换为具体的代码,
    19         IDEA 需要添加 lombok 插件 -->
    20         <dependency>
    21             <groupId>org.projectlombok</groupId>
    22             <artifactId>lombok</artifactId>
    23             <version>1.16.18</version>
    24         </dependency>
    25         <dependency>
    26             <groupId>org.springframework.boot</groupId>
    27             <artifactId>spring-boot-starter-test</artifactId>
    28             <scope>test</scope>
    29         </dependency>
    30     </dependencies>
    31 
    32     <!-- 标识 SpringCloud 的版本 -->
    33     <dependencyManagement>
    34         <dependencies>
    35             <dependency>
    36                 <groupId>org.springframework.cloud</groupId>
    37                 <artifactId>spring-cloud-dependencies</artifactId>
    38                 <version>${spring-cloud.version}</version>
    39                 <type>pom</type>
    40                 <scope>import</scope>
    41             </dependency>
    42         </dependencies>
    43     </dependencyManagement>
    44 
    45     <!-- 配置远程仓库 -->
    46     <repositories>
    47         <repository>
    48             <id>spring-milestones</id>
    49             <name>Spring Milestones</name>
    50             <url>https://repo.spring.io/milestone</url>
    51             <snapshots>
    52                 <enabled>false</enabled>
    53             </snapshots>
    54         </repository>
    55     </repositories>

    创建 Eureka注册服务子模块

    • pom.xml中引入必要的依赖以及插件
       <!-- 模块名及描述信息 -->
        <name>spring-cloud-eureka</name>
        <description>Spring Cloud Eureka</description>
    
        <!-- eureka server: 提供服务发现与服务注册 -->
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
            </dependency>
        </dependencies>
    
        <!--
            SpringBoot的Maven插件, 能够以Maven的方式为应用提供SpringBoot的支持,可以将
            SpringBoot应用打包为可执行的jar或war文件, 然后以通常的方式运行SpringBoot应用
         -->
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    • 资源文件夹(resources)中创建application.yml
    spring:
      application:
        name: spring-cloud-eureka
    
    server:
      port: 8000
    
    eureka:
      instance:
        hostname: localhost
      client:
        fetch-registry: false
        register-with-eureka: false
        service-url:
          defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
    • 启动类上,加上两个注解@EnableEurekaServer@SpringBootApplication

    启动

    方式一:Teriminal窗口

    /** 进入项目目录 */

    cd 项目名

    /** 将项目打包成jar */

    mvn clean package -Dmaven.test.skip=true -U

    /** 进入target目录 */

    cd target

    /** 用jar命令启动项目 */

    java -jar 项目名.jar

    方式二

    直接运行application,启动即可

    上面是Eureka的单节点启动方式,公司中一般为了防止Eureka单节点故障,下面介绍Eureka的多节点伪集群配置方式

    • 在原项目资源文件夹下创建bootstrap.yml,注释掉application.yml中的配置,因为在springBoot项目中会先加载bootstrap.yml
    • 修改Windows中C:WindowsSystem32driversetc路径下的hosts文件
    127.0.0.1 server1
    127.0.0.1 server2
    127.0.0.1 server3

    bootstrap.yml:

    spring:
      application:
        name: spring-cloud-eureka
      profiles: server1
    server:
      port: 8000
    eureka:
      instance:
        hostname: server1
        prefer-ip-address: false
      client:
        service-url:
          defaultZone: http://server2:8001/eureka/,http://server3:8002/eureka/
    
    ---
    spring:
      application:
        name: spring-cloud-eureka
      profiles: server2
    server:
      port: 8001
    eureka:
      instance:
        hostname: server2
        prefer-ip-address: false
      client:
        service-url:
          defaultZone: http://server1:8000/eureka/,http://server3:8002/eureka/
    
    ---
    spring:
      application:
        name: spring-cloud-eureka
      profiles: server3
    server:
      port: 8002
    eureka:
      instance:
        hostname: server3
        prefer-ip-address: false
      client:
        service-url:
          defaultZone: http://server1:8000/eureka/,http://server2:8001/eureka/

    以上配置完成后,在以上启动方式一的基础上,在启动时需加上一个命令,以表示启动哪个Eureka节点

    java -jar 项目名.jar --spring.profiles.active=server1 #标识启动Eureka的server1的服务,以此类推

    启动完成后可在浏览器中访问

    http://127.0.0.1:8000/

    父模块中创建zuul网关服务

    pom.xml中引入相关依赖、插件

        <!-- 模块名及描述信息 -->
        <name>spring-cloud-zuul</name>
        <description>Spring Cloud Gateway</description>
    
        <dependencies>
            <!--
                Eureka 客户端, 客户端向 Eureka Server 注册的时候会提供一系列的元数据信息, 例如: 主机, 端口, 健康检查url等
                Eureka Server 接受每个客户端发送的心跳信息, 如果在某个配置的超时时间内未接收到心跳信息, 实例会被从注册列表中移除
            -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <!-- 服务网关 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
            </dependency>
            <!-- apache 工具类 -->
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>1.3.2</version>
            </dependency>
        </dependencies>
    
        <!--
            SpringBoot的Maven插件, 能够以Maven的方式为应用提供SpringBoot的支持,可以将
            SpringBoot应用打包为可执行的jar或war文件, 然后以通常的方式运行SpringBoot应用
         -->
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>

    资源文件夹中创建application.yml

    spring:
      application:
        name: spring-cloud-zuul
    
    server:
      port: 9000
    
    eureka:
      client:
        service-url:
          defaultZone: http://server1:8000/eureka
    
    zuul:
      prefix: /vast
      routes:
        course:
          path: /course/**
          serviceId: spring-cloud-course-service
          strip-prefix: false
        user:
          path: /user/**
          serviceId: spring-cloud-user-service
          strip-prefix: false

    启动类添加两个注解

    @SpringCloudApplication
    @EnableZuulProxy

    注意:这两个注解和Eureka中启动类中声明的注解是不一样的

    创建两个过滤类,来计算不同URL请求到响应时所需要的时间

    PreFilter.class
    package com.vast.zuul.filters;
    
    import com.netflix.zuul.ZuulFilter;
    import com.netflix.zuul.context.RequestContext;
    import com.netflix.zuul.exception.ZuulException;
    import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
    import org.springframework.stereotype.Component;
    
    @Component
    public class PreFilter extends ZuulFilter {
        @Override
        public String filterType() {
            return FilterConstants.PRE_TYPE;
        }
    
        @Override
        public int filterOrder() {
            return 0;
        }
    
        @Override
        public boolean shouldFilter() {
            return true;
        }
    
        @Override
        public Object run() throws ZuulException {
            RequestContext currentContext = RequestContext.getCurrentContext();
            currentContext.set("startTime", System.currentTimeMillis());
            return null;
        }
    }

     AccessLogFilter.class

    package com.vast.zuul.filters;
    
    import com.netflix.zuul.ZuulFilter;
    import com.netflix.zuul.context.RequestContext;
    import com.netflix.zuul.exception.ZuulException;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
    import org.springframework.stereotype.Component;
    
    import javax.servlet.http.HttpServletRequest;
    
    @Slf4j
    @Component
    public class AccessLogFilter extends ZuulFilter {
        @Override
        public String filterType() {
            return FilterConstants.POST_TYPE;
        }
    
        @Override
        public int filterOrder() {
            return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 1;
        }
    
        @Override
        public boolean shouldFilter() {
            return true;
        }
    
        @Override
        public Object run() throws ZuulException {
            RequestContext currentContext = RequestContext.getCurrentContext();
            Long startTime = (Long) currentContext.get("startTime");
            HttpServletRequest request = currentContext.getRequest();
            String requestURI = request.getRequestURI();
            Long duration = System.currentTimeMillis() - startTime;
            log.info("uri:{},duration:{}ms", requestURI, duration / 100);
            return null;
        }
    }

     在父模块下再创建一个子模块服务,作为另外几个服务的父模块(spring-cloud-service)

    • 删掉不需要的src文件夹
    • 在pom.xml中添加
    <packaging>pom</packaging>
    • 在该模块下,建立公共服务spring-cloud-common

    在服务于服务之间,会有一些公共使用的类或方法,避免重复创建以及维护困难,建立公共模块

    • 在pom.xml引入一些依赖
        <dependencies>
            <!-- JSON 处理工具 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.31</version>
            </dependency>
            <!-- apache 提供的一些工具类 -->
            <dependency>
                <groupId>commons-codec</groupId>
                <artifactId>commons-codec</artifactId>
                <version>1.9</version>
            </dependency>
        </dependencies>
    • 在src目录下创建需要用到的公共类

    在当前父模块(spring-cloud-service)中创建一个课程服务模块(spring-cloud-course-service)

    • 在pom.xml中引入相关依赖以及插件
        <dependencies>
            <!-- 引入 Web 功能 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--
                Eureka 客户端, 客户端向 Eureka Server 注册的时候会提供一系列的元数据信息, 例如: 主机, 端口, 健康检查url等
                Eureka Server 接受每个客户端发送的心跳信息, 如果在某个配置的超时时间内未接收到心跳信息, 实例会被从注册列表中移除
            -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <!-- Java Persistence API, ORM 规范 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <!-- MySQL 驱动, 注意, 这个需要与 MySQL 版本对应 -->
            <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>6.0.6</version>
            </dependency>
            <!-- 通用模块 -->
            <dependency>
                <groupId>com.vast.spring-cloud</groupId>
                <artifactId>spring-cloud-common</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
        </dependencies>
    
        <!--
            SpringBoot的Maven插件, 能够以Maven的方式为应用提供SpringBoot的支持,可以将
            SpringBoot应用打包为可执行的jar或war文件, 然后以通常的方式运行SpringBoot应用
         -->
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    • 创建application.yml
    server:
      port: 7001
      servlet:
        context-path: /course
    
    spring:
      application:
        name: spring-cloud-course-service
      jpa:
        show-sql: true
        hibernate:
          ddl-auto: none
        properties:
          hibernate.format_sql: true
        open-in-view: false
      datasource:
        url: jdbc:mysql://127.0.0.1:3306/test?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
        username: root
        password: root
        driver-class-name: com.mysql.cj.jdbc.Driver
        tomcat:
          max-active: 4
          min-idle: 2
          initial-size: 2
    
    eureka:
      client:
        service-url:
          defaultZone: http://server1:8000/eureka/
    • 在启动类中添加三个注解

    @SpringBootApplication

    /** 向Eureka中注册服务  */

    @EnableEurekaClient

    /** 用JPA来管理数据 */

    @EnableJpaAuditing

    • 建立实体类
    package com.vast.entry;
    
    import lombok.AllArgsConstructor;
    import lombok.Builder;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    import org.springframework.data.annotation.CreatedDate;
    import org.springframework.data.annotation.LastModifiedDate;
    import org.springframework.data.jpa.domain.support.AuditingEntityListener;
    
    import javax.persistence.*;
    import java.util.Date;
    
    @Data
    /* 表明该实体类中的setter方法是private的,需要通过Builder进行build() **/ @Builder @Entity @NoArgsConstructor @AllArgsConstructor
    /** 用来通过注解自动向数据库中插入时间 */ @EntityListeners(AuditingEntityListener.
    class) @Table(name = "t_course") public class CoursePo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") /** 自增 id */ private Long id; @Column(name = "course_name", nullable = false) /** 课程名称 */ private String courseName; @Column(name = "course_type", nullable = false) /** 课程类型 */ private Integer courseType; @Column(name = "course_icon", nullable = false) /** 课程图标 */ private String courseIcon; @Column(name = "course_intro", nullable = false) /** 课程介绍 */ private String courseIntro; @CreatedDate @Column(name = "create_time") /** 创建时间 */ private Date createTime;
    /** Basic用来表明是列,默认的,不用写也是可以的 */ @Basic @LastModifiedDate @Column(name
    = "update_time") /** 更新时间 */ private Date updateTime; }
    • 创建Dao
    package com.vast.dao;
    
    import com.vast.entry.CoursePo;
    import org.springframework.data.jpa.repository.JpaRepository;
    /** Jpa中有许多已经配置好的方法,以及查询规则,只要按照其指定的规则来即可快速操作数据库中的数据 */
    public interface CourseDao extends JpaRepository<CoursePo, Long> {
    }
    • 课程实现类 CourseImpl
    package com.vast.service.impl;
    
    import com.vast.service.ICourseService;
    import com.vast.common.entry.Course;
    import com.vast.common.entry.RequestContent;
    import com.vast.dao.CourseDao;
    import com.vast.entry.CoursePo;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.util.CollectionUtils;
    
    import java.util.Collections;
    import java.util.List;
    import java.util.Optional;
    import java.util.stream.Collectors;
    
    @Service
    public class CourseImpl implements ICourseService {
        @Autowired
        private CourseDao courseDao;
    
        @Override
        public Course getCourseById(Long id) {
            Optional<CoursePo> course = courseDao.findById(id);
    /** java8特性,Lambda表达式,判断实体类是否为空,防止抛出空指针异常 */
    return builderCoursePo(course.orElseGet(() ->
    CoursePo.invalid())); } @Override public List<Course> getCourseListByIds(RequestContent requestContent) { List<Long> ids = requestContent.getIds(); if (CollectionUtils.isEmpty(ids)) { return Collections.emptyList(); } List<CoursePo> courseList = courseDao.findAllById(ids);
    /** java8 特性 */
    return courseList.stream().map(this::builderCoursePo) .collect(Collectors.toList()); } /** * @param course * @return * @Description 构造课程信息
    * Builder使用方法
    */ public Course builderCoursePo(CoursePo course) { return Course.builder() .courseIcon(course.getCourseIcon()) .courseIntro(course.getCourseIntro()) .courseName(course.getCourseName()) .courseType(course.getCourseType() == 0 ? "SpringCloud" : "SSM") .build(); } }

    测试类

    •  启动类中添加注解

    @SpringBootApplication

    • 测试类中添加注解

    @RunWith(SpringRunner.class)

    @SpringBootTest(classes = {TestCourseApplication.class}, webEnvironment = SpringBootTest.WebEnvironment.NONE)

     在当前父模块(spring-cloud-service)中创建一个课程服务模块(spring-cloud-user-service)

    •  在pom.xml中引入相关依赖、插件
        <dependencies>
            <!-- 引入 Web 功能 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <!--
                Eureka 客户端, 客户端向 Eureka Server 注册的时候会提供一系列的元数据信息, 例如: 主机, 端口, 健康检查url等
                Eureka Server 接受每个客户端发送的心跳信息, 如果在某个配置的超时时间内未接收到心跳信息, 实例会被从注册列表中移除
            -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <!-- 引入 Feign, 可以以声明的方式调用微服务 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>
            <!-- 引入服务容错 Hystrix 的依赖 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            </dependency>
            <!-- Java Persistence API, ORM 规范 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <!-- MySQL 驱动, 注意, 这个需要与 MySQL 版本对应 -->
            <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>6.0.6</version>
            </dependency>
            <!-- 通用模块 -->
            <dependency>
                <groupId>com.vast.spring-cloud</groupId>
                <artifactId>spring-cloud-common</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
            <dependency>
                <groupId>org.jetbrains</groupId>
                <artifactId>annotations</artifactId>
                <version>RELEASE</version>
                <scope>compile</scope>
            </dependency>
        </dependencies>
    
        <!--
            SpringBoot的Maven插件, 能够以Maven的方式为应用提供SpringBoot的支持,可以将
            SpringBoot应用打包为可执行的jar或war文件, 然后以通常的方式运行SpringBoot应用
         -->
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    • 在资源文件夹创建application.yml
    server:
      port: 7000
      servlet:
        context-path: /user
    
    spring:
      main:
        allow-bean-definition-overriding: true
      application:
        name: spring-cloud-user-service
      jpa:
        show-sql: true
        hibernate:
          ddl-auto: none
        properties:
          hibernate.format_sql: true
        open-in-view: false
      datasource:
        url: jdbc:mysql://127.0.0.1:3306/test?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8
        username: root
        password: root
        driver-class-name: com.mysql.cj.jdbc.Driver
        tomcat:
          max-active: 4
          min-idle: 2
          initial-size: 2
    
    eureka:
      client:
        service-url:
          defaultZone: http://server1:8000/eureka/
    
    feign:
      hystrix:
        enabled: true
    • 在启动类添加注解

    /** 支持Feign调用 */

    @EnableFeignClients

    /** 支持服务熔断降级 */

    @EnableCircuitBreaker

    /** 支持JPA */

    @EnableJpaAuditing

    /** 支持想Eureka注册服务 */

    @EnableEurekaClient

    @SpringBootApplication

    • 实现类UserInfoServiceImpl
    package com.vast.service.impl;
    
    import com.vast.client.ICourseFeignClient;
    import com.vast.common.entry.Course;
    import com.vast.common.entry.RequestContent;
    import com.vast.common.entry.User;
    import com.vast.dao.UserCourseDao;
    import com.vast.dao.UserDao;
    import com.vast.entity.UserCourseInfo;
    import com.vast.entity.UserInfo;
    import com.vast.service.IUserService;
    import com.vast.vo.CreateUserRequestVo;
    import com.vast.vo.UserCourseInfoVo;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.util.CollectionUtils;
    
    import java.util.Collections;
    import java.util.List;
    import java.util.Optional;
    import java.util.stream.Collectors;
    
    @Slf4j
    @Service
    public class UserInfoServiceImpl implements IUserService {
        private final UserDao userDao;
        private final UserCourseDao userCourseDao;
        private final ICourseFeignClient iCourseFeignClient;
    
        @Autowired
        public UserInfoServiceImpl(UserDao userDao, UserCourseDao userCourseDao, ICourseFeignClient iCourseFeignClient) {
            this.userDao = userDao;
            this.userCourseDao = userCourseDao;
            this.iCourseFeignClient = iCourseFeignClient;
        }
    
        @Override
        public User getUserInfoById(Long id) {
            Optional<UserInfo> userInfoById = userDao.findById(id);
    /** 判断对象是否为空 */
    if (!userInfoById.isPresent()) { return new User().invalidate(); } return builderUserInfo(userInfoById.get()); } @Override public User createUserInfo(CreateUserRequestVo createUserRequestVo) { /** 判断传的参数是否为空 */ if (!createUserRequestVo.validate()) { return User.invalidate(); } /** 判断该用户在用户表中已存在 */ UserInfo userInfoByUsername = userDao.findByUsername(createUserRequestVo.getUsername()); if (null != userInfoByUsername) { return User.invalidate(); } UserInfo saveUserInfo = userDao.save(new UserInfo(createUserRequestVo.getUsername(), createUserRequestVo.getEmail())); return new User(saveUserInfo.getId(), saveUserInfo.getUsername(), saveUserInfo.getEmail()); } @Override public UserCourseInfoVo getUserCourseInfoById(Long id) { /** 根据用户id判断是否有该用户 */ Optional<UserInfo> userInfoById = userDao.findById(id); if (!userInfoById.isPresent()) { return UserCourseInfoVo.invalidate(); } /** 获取对象 */ UserInfo userInfo = userInfoById.get(); User user = new User(userInfo.getId(), userInfo.getUsername(), userInfo.getEmail()); /** 根据用户id判断用户课程表中是否有该对应的信息 */ List<UserCourseInfo> allUserCourseInfoByUserId = userCourseDao.findAllByUserId(id); if (CollectionUtils.isEmpty(allUserCourseInfoByUserId)) { return new UserCourseInfoVo(Collections.emptyList(), user); } /** 如果用户id在用户表、用户课程表中都存在,则用feign客户端调用课程服务,获取对应 * 的课程信息,并将用户、课程信息进行返回 * */ List<Course> coursesByIds = iCourseFeignClient.getCoursesByIds(new RequestContent(allUserCourseInfoByUserId.stream() .map(UserCourseInfo::getCourseId).collect(Collectors.toList()))); return new UserCourseInfoVo(coursesByIds, user); } private User builderUserInfo(UserInfo userInfo) { return User.builder() .id(userInfo.getId()) .email(userInfo.getEmail()) .username(userInfo.getUsername()) .build(); } }
    • Feign调用客户端
    package com.vast.client;
    
    import com.vast.common.entry.Course;
    import com.vast.common.entry.RequestContent;
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.*;
    
    import java.util.List;
    /** 1.FeignClient表明是Feign调用;
    * 2.value表明是调用哪个服务实例;
    * 3.fallback是表明熔断时调用哪个类;
    * 4.@RequestMapping中的请求方式以及URL和所调用的服务的控制层中的保持一致
    */ @FeignClient(value
    = "spring-cloud-course-service", fallback = CourseHystrixClient.class) public interface ICourseFeignClient { @RequestMapping(value = "/get/course/", method = RequestMethod.GET) public Course getCourseInfoById(Long id); @RequestMapping(value = "/get/courses", method = RequestMethod.POST) public List<Course> getCoursesByIds(@RequestBody RequestContent requestContent); }
    • Hystrix
    package com.vast.client;
    
    import com.vast.common.entry.Course;
    import com.vast.common.entry.RequestContent;
    import org.springframework.stereotype.Component;
    
    import java.util.Collections;
    import java.util.List;
    /** 1.@Component声明该类是spring的bean实例;
    * 2.实现Feign客户端接口方法;
    * 3.进行熔断处理;
    */
    @Component
    public class CourseHystrixClient implements ICourseFeignClient { @Override public Course getCourseInfoById(Long id) { return Course.inValidEntry(); } @Override public List<Course> getCoursesByIds(RequestContent requestContent) { return Collections.emptyList(); } }

    测试类

    •  启动类中添加注解

    @EnableFeignClients(basePackages = {"com.vast"})

    @SpringBootApplication

    • 测试类中添加注解

    @RunWith(SpringRunner.class)

    @SpringBootTest(classes = CourseApplication.class)

    效果图

  • 相关阅读:
    CSP内容安全策略总结及如何抵御 XSS 攻击
    CORS跨域资源共享总结
    web安全总结
    小知识随手记(八)
    内存泄漏问题总结
    Vue中插槽slot的使用
    Git常用命令、及常见报错处理:You have not concluded your merge (MERGE_HEAD exists)、清理无效的远程追踪分支
    render函数、createElement函数与vm.$slots
    Redis集群(二):Redis的安装
    Shell命令_文件系统常用命令df、du
  • 原文地址:https://www.cnblogs.com/yanduanduan/p/11989641.html
Copyright © 2011-2022 走看看