zoukankan      html  css  js  c++  java
  • JeecgBoot使用总结Feign的使用总结

    当系统为微服务时,需要模块之间的调用,但是不太方便直接将模块整个引入,所以就需要使用Feign进行调用,使用步骤进行总结,比如A模块准备调用B模块的C方法,按照这个进行整理。

    第一步:

    因为要调用B模块,所以需要在B模块创建一个对外的服务接口,并将业务进行实现,代码如下:

    package org.jeecg.modules.api.controller;
    /**
     * 服务化 system模块 对外接口请求类
     */
    @Api(tags="对外接口请求类")
    @RestController
    @RequestMapping("/sys/api")
    @Slf4j
    public class SystemAPIController extends BaseController {
    
        @Resource
        private SysUserMapper userMapper;
    
        ....../**
         * 37根据多个用户id(逗号分隔),查询返回多个用户信息
         * @param ids
         * @return
         */
        //todo feign 第三步在该模块声明接口
        @RequestMapping("/queryUsersById")
        LoginUser queryUsersById(@RequestParam("ids") String ids){
            log.info("fegin远程调用:第三步");
            //return this.sysBaseAPI.queryUsersById(ids);
            log.info("fegin远程调用:直接隔断");
            SysUser user = userMapper.selectById(ids);
            LoginUser loginUser = new LoginUser();
            if (user!=null){
                loginUser.setId(user.getId());
                loginUser.setAvatar(user.getAvatar());
                loginUser.setRealname(user.getRealname());
            }
            return loginUser;
        }
      ......
    }

    以上代码中的对外接口就是”/sys/api/queryUsersById“。

    第二步:

    因为A模块调用B模块,也会存在其他模块之间的调用,为了提供公共的对外接口,就需要一个额外的公共api模块,于是有了如下路径

    jeecg-boot-base\jeecg-boot-base-api\jeecg-system-cloud-api\src\main\java\org\jeecg\common\system\api\ISysBaseAPI.java

    为了区分是单体还是微服务,使用jeecg-system-cloud-api以及jeecg-system-local-api,也就是cloud和local进行区分。因为咱们使用的是微服务,所以重点说一下cloud模块。

    在cloud模块中还有一下分类,system.api、online.api、bpm.api,见明知义,主要是按照你调用模块的简称进行区分,调用jeecg-system模块的api全都写在system这个api中。

    每个模块中的文件夹都是固定的,接下来简单说一下每个文件夹中文件的作用

     如图片所示,先简单说一下2和3,其实他们就是一个东西,熔断器,主要增加一层保险,当接口查询不到数据,默认返回一些假数据,从而达到防止系统查询不到数据导致崩溃的作用。2和3中有对方法的一些重写,其实就是一模一样的接口再重新写一遍,但是返回的值

    正常的话会进行处理,具体的使用看下边代码中标红的fallbackFactory参数

    接下来就是重点说1的作用了,1其实就是对位的api接口,底层通过http请求来找到对应模块中的接口。代码如下:

    package org.jeecg.common.system.api;
    @Component
    @FeignClient(contextId = "sysBaseRemoteApi", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = SysBaseAPIFallbackFactory.class)
    public interface ISysBaseAPI extends CommonAPI {
    
        ......//todo feign 第一步声明接口
        @RequestMapping("/sys/api/queryUsersById")
        LoginUser queryUsersById(@RequestParam("ids") String ids);
    
        ......
    
    }
      //在接口上加 @FeignClient 注解来声明 一个Feign Client,其中 value 为 远程调用其他服务的服务名
      //FeignConfig.class 为 Feign Client 的配置类,注入Retryer类的实例,这样在远程调用失败后,feign会进行重试
      //使用 Spring MVC 的注解来绑定具体该服务提供的 REST 接口
      //fallback 配置回调处理类,该处理类是作为 Feign 熔断器的逻辑处理类,实现FeignHystrixInter 接口
      //fallbackFactory(类似于断容器)与fallback方法。

    看到标红的地方没,有没有很熟悉,其实就是第一步中所谓的对外接口,这下基本上就已经对应上了。

    需要重点注意@FeignClient后边的三个参数。

    • contextId:api接口的id
    • value:对应模块的名称
    • fallbackFactory:熔断器的文件地址

    第三步:

    前两步将准备工作已经做好,接下来就只需要引用然后调用即可。

    在B模块启动类中,先启用Feign,代码如下:

    package org.jeecg;
    import lombok.extern.slf4j.Slf4j;
    import org.jeecg.common.util.oConvertUtils;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.openfeign.EnableFeignClients;
    import org.springframework.context.ConfigurableApplicationContext;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.core.env.Environment;
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    @Slf4j
    @EnableDiscoveryClient
    @SpringBootApplication
    @EnableFeignClients
    public class JeecgknowledgeCloudApplication extends SpringBootServletInitializer {
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
            return application.sources(JeecgknowledgeCloudApplication.class);
        }
        public static void main(String[] args) throws UnknownHostException {
            long startTime = System.currentTimeMillis();    //获取开始时间
            ConfigurableApplicationContext application = SpringApplication.run(JeecgknowledgeCloudApplication.class, args);
            Environment env = application.getEnvironment();
            String ip = InetAddress.getLocalHost().getHostAddress();
            String port = env.getProperty("server.port");
            String path = oConvertUtils.getString(env.getProperty("server.servlet.context-path"));
            log.info("\n----------------------------------------------------------\n\t" +
                    "Application Jeecg-Boot is running! Access URLs:\n\t" +
                    "Local: \t\thttp://localhost:" + port + path + "/doc.html\n" +
                    "External: \thttp://" + ip + ":" + port + path + "/doc.html\n" +
                    "Swagger文档: \thttp://" + ip + ":" + port + path + "/doc.html\n" +
                    "----------------------------------------------------------");
            System.out.println("=====知识库-启动成功=====");
            long endTime = System.currentTimeMillis();    //获取结束时间
            System.out.println("程序运行时间:" + (endTime - startTime)/1000 + "");    //输出程序运行时间
        }
    }

    标红的位置是在启动类启动fegin的服务应用,然后引入api的模块,接着在你需要的类中引用“ISysBaseAPI”这个类,从而去引用你想要引用的方法

    package org.jeecg.modules.wiki.service.impl;/**
     * @Description: 页面信息
     * @Author: jeecg-boot
     * @Date:   2021-11-12
     * @Version: V1.0
     */
    @Service
    @DS("knowledge")
    public class ContentServiceImpl extends ServiceImpl<ContentMapper, Content> implements IContentService {
    
        @Autowired
        private  ContentMapper contentMapper;
    
        @Autowired
        private BodycontentMapper bodycontentMapper;
    
        @Autowired
        private IBodycontentService iBodycontentService;
    
        @Autowired
        private ISysBaseAPI iSysBaseAPI;
    
        ......
    
        @Override
        public List<ContentVO> getAlllatelyWork(Content content) {
            List<ContentVO> list =new ArrayList<>();
            LoginUser user01 =  iSysBaseAPI.queryUsersById("e9ca23d68d884d4ebb19d07889727dae"); // 系统用户信息
            log.debug("数据查询:"+user01.getUsername());
            List<ContentVO> contentVOList = contentMapper.getUserWork(DateUtil.getDate(),DateUtil.getupperDate(),content.getUsername());
            if (contentVOList.size()>0&&contentVOList!=null){
                for (ContentVO contentVO : contentVOList) {
                    if (!StringUtils.isEmpty(contentVO.getUsername())){
                        LoginUser user =  iSysBaseAPI.queryUsersById(contentVO.getUsername()); // 系统用户信息
                        if (user!=null){
                            contentVO.setLastName(user.getRealname());
                            contentVO.setActive(user.getAvatar());
                        }
                    }
                    list.add(contentVO);
                }
    
            }
            return list;
        }
    
    }

    以上过程就完成了模块之间的调用了。

    对于feign参数的使用也进行过总结,链接:Feign使用总结-参数传递

    大致的流程图如下:

     注意:

    有些模块已经引用了ISysBaseAPI这个类,但是调用的是local模块,通过以上的流程图进行调用的,当需要一个新的Feign接口时,一定要注意按照已经存在的形式进行使用,不能直接引用以下代码,不然本该走local的直接走cloud,就会导致启动异常。

         <dependency>
                <groupId>org.jeecgframework.boot</groupId>
                <artifactId>jeecg-system-cloud-api</artifactId>
            </dependency>

    eg:jeecg-boot-module-system模块中JimuReportTokenService类中引用代码(部分)

    /**
     * 自定义积木报表鉴权(如果不进行自定义,则所有请求不做权限控制)
     *  * 1.自定义获取登录token
     *  * 2.自定义获取登录用户
     */
    @Component
    public class JimuReportTokenService implements JmReportTokenServiceI {
        @Autowired
        private ISysBaseAPI sysBaseAPI;

    在没有引cloud之前走的是local,在引用后走的是cloud。就会导致出现问题。

  • 相关阅读:
    Spring事务的传播行为、隔离级别、回滚、只读和过期
    Spring 使用XML文件的方式配置事务
    SpringJDBCTemplate
    Spring事物管理
    【运维技术】Zookeeper单机以及集群搭建教程
    【运维技术】kafka三实例集群环境搭建及测试使用
    【运维技术】redis(一主两从三哨兵模式搭建)记录
    【运维技术】shell脚本实现线程挂掉,自动重启功能
    【运维技术】slc pm 启动不了,异常排除问题记录
    【知识总结】Java类初始化顺序说明
  • 原文地址:https://www.cnblogs.com/qcq0703/p/15684968.html
Copyright © 2011-2022 走看看