美文网首页
随手写个 Spring Boot微服务节点

随手写个 Spring Boot微服务节点

作者: AllenJoker | 来源:发表于2020-03-03 23:23 被阅读0次

    随手写个 Spring Boot微服务节点

    当年前圈内各路神仙开始实践服务拆分,开始做SOA, 6年前兴起的微服务,近几年火热的SpringCloud, 最近边车模式开始流行ServiceMesh服务网格.微服务在我们面前反复横跳, 顺手耗掉你几根头毛的同时不说吸还吸粉无数.今天我卢本伟随手写个微服务节点不是问题.

    image

    构建Spring Boot maven多模块项目

    使用IDEA构建多模块maven 项目骨架, 基本操作不多bb.

    Spring Boot 版本选择2.2.4

    • 打开idea选择new project选择Spring Initializr 创建第一个Springboot项目 image
    • 保留以下文件,其他文件都删除 image
    • 构建maven子模块 image image
    • 将多余文件删除, 将pom中<parent>修改为如下所示[图片上传失败...(image-99397-1583248865412)]
    • web模块在构造的时候重复上面的步骤, 并勾选Spring Web选项 image

    模块功能

    demo
    |-- demo-api      jar文件 API二方包
    |-- demo-core     jar文件 核心业务层
    |-- demo-data     jar文件 持久层
    |-- demo-server   jar文件 provider,发布的web服务
    |-- demo-util     jar文件 工具包
    `-- pom.xml       maven 发布文件
    

    集成ORM框架Mybatis

    集成方案

    目前我知道的有四种方式:

    • Mybatis + XML
    • Mybatis + 注解
    • Mybatis-Plus
    • tkmybatis
      这里我们选用Mybatis-Plus这种方式集成,原因有以下几点:
    1. 相比 Mybatis + XML 配置项来说,Mybatis-Plus 增加了更多配置项,也因此我们无需在配置 mybatis-config.xml 配置文件

    2. Mybatis-Plus增加BaseMapper接口, 常规CRUD可以替我们自动生成

      • insert(DO do)
      • updateById(DO do)
      • deleteById(@Param("id") Integer id)
      • selectById(@Param("id") Integer id)
    3. 注解的方式不适合排版SQL, 且mapper接口很长显得杂乱

    • Mybatis官方文档
    • 因为最初设计时,MyBatis 是一个 XML 驱动的框架.配置信息是基于 XML 的,而且映射语句也是定义在 XML 中的.而到了 MyBatis 3,就有新选择了.MyBatis 3 构建在全面且强大的基于 Java 语言的配置 API 之上.这个配置 API 是基于 XML 的 MyBatis 配置的基础,也是新的基于注解配置的基础.注解提供了一种简单的方式来实现简单映射语句,而不会引入大量的开销.
    • 不幸的是,Java 注解的的表达力和灵活性十分有限.**尽管很多时间都花在调查、设计和试验上,最强大的 MyBatis 映射并不能用注解来构建——并不是在开玩笑,的确是这样.比方说,C#属性就没有这些限制,因此 MyBatis.NET 将会比 XML 有更丰富的选择.也就是说,基于 Java 注解的配置离不开它的特性.

    就是说他们自己也不推荐这种写法.

    1. tkmybatis 是多个开源项目组合起来的, tk是toolkit 的缩写.

    建议

    不要在 service 中使用 QueryWrapper 拼接动态条件, 这样业务逻辑层会充斥着各种查询,不方便做统一管理.

    Mybatis-Plus

    https://mp.baomidou.com/

    maven配置

    <!--全局变量-->
    <properties>
        <mysql.version>5.1.48</mysql.version>
        <mybatis.plus.version>3.2.0</mybatis.plus.version>
        <pagehelper.version>1.2.13</pagehelper.version>
    </properties>
    <!-- mysql -->
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>${mysql.version}</version>
                </dependency>
                <!-- orm mybatis-->
                <dependency>
                    <groupId>com.baomidou</groupId>
                    <artifactId>mybatis-plus-annotation</artifactId>
                    <version>${mybatis.plus.version}</version>
                    <scope>compile</scope>
                </dependency>
                <dependency>
                    <groupId>com.baomidou</groupId>
                    <artifactId>mybatis-plus-boot-starter</artifactId>
                    <version>${mybatis.plus.version}</version>
                </dependency>
                <!-- pagehelper -->
                <dependency>
                    <groupId>com.github.pagehelper</groupId>
                    <artifactId>pagehelper-spring-boot-starter</artifactId>
                    <version>${pagehelper.version}</version>
                </dependency>
    

    Mybatis-Plus配置

    @Configuration
    @MapperScan(basePackages = "com.barm.demo.data.*")
    public class MybatisPlusConfig {
    }
    

    application.yaml

    spring:
      datasource:
        url: jdbc:mysql://127.0.0.1:3306/demo?useSSL=false&useUnicode=true&characterEncoding=UTF-8
        driver-class-name: com.mysql.jdbc.Driver
        username: root
        password: 123456
    
    mybatis-plus:
      global-config:
        db-config:
          logic-delete-field: flag  
          id-type: auto
      mapper-locations: classpath:mapper/*.xml
      type-aliases-package: com.barm.demo.domain
    
    logging:
      level:
        cn:
          iocoder:
            springboot:
              lab12:
                mybatis:
                  mapper: debug
    

    其他

    更多配置项,参考 MyBatis-Plus 使用配置

    IDEA插件

    看到这里有的观众老爷可能会问为“为啥没MybatisGenerate模块?”, 这里我们推荐使用MyBatisCodeHelper-Pro, Intellij下Mybatis插件.一个不错的生产力工具.

    放上几个操作感受一下.

    • 根据DO生成DDL image
    • 生成Mapper image
    • 添加属性重复上面操作可直接修改原文件 image
    • 根据方法生成Mapper接口及xml,命名当时类似JPA image
    • 从Mapper中生成对应Service方法实现 image
    • 生成service分页方法,这里使用的是google的PageHelper image

      这个插件是收费的, 但是依然提供了很多免费功能, 可体验一个月.有兴趣的小伙伴可以试试.

    抽象出全局common包

    用于统一服务之间的交互格式,和一些常用的工具类

    github源码地址: https://github.com/allennotes/common

    maven 配置

    <properties>
        <common.version>1.0.0SNAPSHOT</common.version>
    </properties>  
    <dependency>
        <groupId>com.barm</groupId>                                  <artifactId>common</artifactId>
        <version>${common.version}</version>
    </dependency>
    

    异常统一处理

    • 定义公用系统异常
    @Getter
    public class ApplicationException extends Exception{
        
        /** 结果枚举*/
        private final ResultEnum resultEnum;
        /** 自定义异常信息*/
        private String errMsg;
        /** 异常码 */
        private Integer errCode;
    
        public ApplicationException(ResultEnum resultEnum) {
            super(resultEnum.getMsg());
            this.errCode = resultEnum.getCode();
            this.errMsg = resultEnum.getMsg();
            this.resultEnum = resultEnum;
        }
    
        public ApplicationException(String errMsg) {
            super(ResultEnum.FAIL.getMsg());
            this.errCode = ResultEnum.FAIL.getCode();
            this.errMsg = errMsg;
            this.resultEnum = ResultEnum.FAIL;
        }
    }
    
    • 如果全部异常处理返回json,那么可以使用 @RestControllerAdvice 代替 @ControllerAdvice
    @Slf4j
    @RestControllerAdvice
    public class ExceptionHandlers {
        @ExceptionHandler(value = ApplicationException.class)
        public ResultVO applicationException(ApplicationException e){
            log.error("exception for system", e);
            return new ResultVO(ResultEnum.FAIL);
        }
    
        @ExceptionHandler(value = RuntimeException.class)
        public ResultVO runtimeException(RuntimeException e){
            log.error("exception for runtime", e);
            ResultVO resultVO = new ResultVO(ResultEnum.FAIL);
            return resultVO;
        }
    }
    

    基于线程池的异步注解

    从Spring3开始提供了@Async注解,这里我们无需引入直接上配置.

    @EnableAsync
    @Configuration
    public class AsyncConfig {
    
        private static final int corePoolSize = 10;
        private static final int maxPoolSize = 50;
        private static final int keepAliveTime = 10;
        private static final int queueCapacity = 100000;
        private static final String threadNamePrefix = "Async-Executor-";
    
        @Bean
        public ThreadPoolTaskExecutor getAsyncExecutor(){
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(corePoolSize);
            executor.setMaxPoolSize(maxPoolSize);
            executor.setQueueCapacity(queueCapacity);
            executor.setKeepAliveSeconds(keepAliveTime);
            executor.setThreadNamePrefix(threadNamePrefix);
            // 线程池对拒绝任务的处理策略
            executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            // 初始化
            executor.initialize();
            return executor;
        }
    }
    

    对象转化

    DO,BO,VO各模块之间的转换, 我们使用mapstruct,请参考属性拷贝你还在用BeanUtils?

    启动项目

    image

    总结

    • 本文主要讲述了使用Spring Boot 快速构建一个微服务节点主要功能
      • MybatisPlus集成
        • 通用增改
        • 统一逻辑删
        • 分页查询
      • 异常统一处理
      • 消息体格式统一
      • 对象转化
      • 基于线程池的异步注解
    • 后续会陆续更新新的功能,例如:
      • 配置注册中心
      • 远程调用
      • 配置缓存
      • 配置消息队列
      • 分布式事务
      • 配置分布式锁
      • 分布式定时任务
      • 配置配置中心
      • 集成token
      • 配置分库分
    • 更多github源码:https://github.com/allennotes/webserver
    • 欢迎issues提问
      这期就这么多了.欢迎大家评论,交流,关注,点赞~


      image

    相关文章

      网友评论

          本文标题:随手写个 Spring Boot微服务节点

          本文链接:https://www.haomeiwen.com/subject/grirlhtx.html