2024年1月17日星期三

分享使用多年简单高效的 spring boot 模板工程结构

尽管目前市场主流编程语言有很多,但 Java 仍然是企业的使用首选,不仅是成长多年,积累了不少 Coder,也在于丰富的开源库,而 spring 全家桶仍然非常流行,本篇文章结合作者多年使用,总结的一个简单的 spring boot 模板结构,具有以下优缺点:

优点:

  • 干净清爽,不依赖任何第三方库,适合手工码字人
  • 一个的业务处理入口(Controller),避免入口泛滥在应用中的各个地方
  • 异常处理、响应结果、摘要日志、鉴权部分的预留等等,同样是避免切面膨胀
  • 研发只需关注业务部分代码的开发,不需要管异常、日志、鉴权等非主流程处理的代码
  • 自定义空间大,模板结构保存很多预留位,可自定义扩展

缺点:

  • 适用于处理通用HTTP业务请求,JSON格式的请求响应体,对于websocket或上传下载等需另行定义处理
  • 业务请求的配置路径在 xml 文件中完成,多人开发容易造成代码冲突

1. 类结构图

1.1. 领域对象

下图主要是领域对象的定义,涵盖异常、错误码与服务结果,错误级别、错误码都是为业务异常服务,出现异常的情况,最终会以正常状态服务结果返回,而不是异常堆栈的直接抛出。

20240118101728

为了更快的创建出模板结构,上面数字代表创建顺序,详细的代码可直接点击查看:

  • CommonResultCode,通用的结果定义,用于约束返回内容
  • ErrorCodeConstants,错误码常量定义,应结合错误码规范,其中包含错误码前缀、错误级别与业务域的定义
  • CommonResultCodeEnum,错误码枚举类的定义,因实现了CommonResultCodeErrorCodeConstants,只需定义自己的四位错误码
  • ServiceResult,响应结果,贯穿整条业务请求,其中定义约束了返回结构,应遵循各自的前后端交互规范
  • AbstractBizException,抽象的业务异常对象,由自定义异常继承
  • CustomBizException,自定义的业务异常,需继承AbstractBizException
  • AssertUtils,断言工具类,与AbstractBizException绑定,业务开发中不必if...else...判断,使用此工具直接抛

完成上面领域对象的定义,在 applicationContext.xml 中配置个异常的 Bean 对象,具体可以看AssertUtils类注释,第一步完成。

<bean class="com.xxx.xxx.exception.AssertUtils">
    <property name="exceptionClassName" value="com.xxx.xxx.exception.CustomBizException"/>
</bean>

1.2. 请求委派

领域对象贯穿业务请求的生命周期,对于每个请求的的扭转委派,如下图定义:

20240118135016

尽管已经最小化,为了简单,仍然用了一些工具类的包,提前配置在 pom.xml 文件中,如下:

<!-- JSON格式处理 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.65</version>
</dependency>

<!-- 工具包 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.8.1</version>
</dependency>

<!-- 日志 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>2.0.10</version>
</dependency>

按上图步骤,依次创建的类如下:

至此所有模板代码已创建完成,下面看如何使用。

2. 模板使用

2.1. 编写服务

DelUser,继承AbstractServiceCallback类,必需要实现executeService方法,beforeServiceafterService 可选

import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Component;

@Component("deleteUser")
public class DelUser extends AbstractServiceCallback<ServiceRequest, ServiceResult<String>> {

    /**
     * 前置处理(可选的方法),生命周期在 executeService 执行之前
     * 可以做一些参数校验等操作
     *
     * @param request 服务请求对象
     */
    @Override
    public void beforeService(ServiceRequest request) {
        super.beforeService(request);

        // 参数验证
        JSONObject postJson = request.parseData(JSONObject.class);
        AssertUtils.notNull(postJson, CommonResultCodeEnum.PARAM_ILLEGAL, "post data is null");

        Long id = postJson.getLong("id");
        AssertUtils.notNull(id, CommonResultCodeEnum.PARAM_ILLEGAL, "id is null");
    }

    @Override
    public ServiceResult executeService(ServiceRequest request) {
        // 获取返回对象,最终将在 result 的 T data 中呈现
        String resultData = "ok";

        return ServiceResult.valueOfSuccess(resultData);
    }

    /**
     * 后置处理(可选的方法),生命周期在 executeService 执行完后
     * 可以做回收的操作
     *
     * @param request 服务请求对象
     * @param result {@link ServiceResult}
     */
    @Override
    public void afterService(ServiceRequest request, ServiceResult result) {
        super.afterService(request, result);
    }
}

2.2. 注册服务

将上面的服务注册到request-mapping.xml文件中,下面的 entry key 就是要请求的路径,如/api/user/delete

<bean id="domainServiceProcess" class="com.cainiao.moore.template.DomainServiceProcessImpl">
    <property name="serviceMap">
        <map>
            <entry key="api_user_delete"  value-ref="deleteUser"/>
        </map>
    </property>
</bean>

2.3. 服务访问

启动 spring boot 应用, 使用 curl 或者 postman 这样的工具发起请求

20240118145639

3. Conclusion

整个服务模板,搭建起来废点事,但实际使用中,会发现非常简单,继承服务回调类,注册服务,技术只需要在自己的服务中编写业务代码,完全不需要关注日志怎么打,异常怎么处理,上层都已进行了封装。

仁者见仁,智者见智,适合自己的才是最好的

4. 代码及素材

2024年1月9日星期二

如何使用 vscode remote tunnel 远程访问本地环境进行代码开发

server-arch-latest

1. 适合什么人

自由开发者,边旅行边工作的技术人,懒惰的不想背电脑的码农,经常要突然处理的IT社畜。

2. 有什么特点

  1. 性能优势,尽管存在众多在线的IDE,但基于商业化的原则,资源的消耗往往需要付费才能使用。而 vscode remote tunnel 不一样,只要网络正常,使用的是远程本地机器资源,不需要担心性能问题。
  2. 环境一致,不同机器或不同的在线IDE,开发环境往往需要提前配置,包括环境变量、依赖安装等等,往往还不能成功编译运行,这样的问题在 vscode remote tunnel 不存在,可以节省很多维护工作。
  3. 可访问性,任何时间、任何地点、任何设备,网络通畅,只要搭载浏览器的设备即可实现远程办公。

总之,VS Code Remote Tunneling 提供了一种灵活而强大的方式,使远程工作更加流畅和高效,特别对于有远程工作需求或需要访问特定远程资源的开发者来说,这是一个很有价值的工具。

3. 有什么缺点

  1. 机器损耗与电费支出,一台常年不关也不休眠的电脑
  2. 网络问题,遇到网络不通,或网速过慢时,体验不好

4. 使用步骤

整体步骤相对简单,在本地(或者说家里)的电脑上开启 vscode remote tunnel,且保持电脑不关机也不休眠(可调低亮度降低资源损耗以及屏幕的使用寿命),在任何地点的电脑上打开浏览器访问 vscode.dev,使用相同的登陆账号访问本地机器进行开发。

4.1. 开启 vscode remote tunnel

在 vscode 中,cmd + shift + p 调出命令面板,输入 remote tunnel,选择 Turn on Remote Tunnel Access 打开远程隧道。

中途可能会提示你使用 Github 或者 Microsoft 账号授权登陆,按步骤操作即可。开启完成,会提示你复制远程连接,可以复制,通过粘贴到浏览器中打开确定可用,之后忘记连接也没有关系,只要远程访问时保持账号一致,也可以看见开启的 remote tunnel 服务。

vscode remote tunnel

开启完,修改电源选项,避免其休眠或关机,关闭显示器或合上笔记本后盖,保持一直运行。

4.2. 浏览器访问 vscode.dev

在任何地方打开浏览器访问 vscode.dev,点击左下角头像使用 Github 或者 Microsoft 账号授权登陆,点击左侧 remote explorer,在 Tunnels 就能看到远程运行的 vscode remote tunnel 隧道服务的机器,默认就是电脑的名称,双击即可进行远程机器的开发环境。

access remote vscode tunnel

5. 使用方法

打开 vscode.dev 连接上 remote tunnel后,也许不是你希望的应用或目录,可以在菜单里打开 终端Terminal,自由使用命令进行操作,尽管这看起来并不安全,因为只要连接到隧道后,你可以做任何事情。

remote tunnel terminal

至此,可以愉快的远程进行开发啦

Reference

2023年12月4日星期一

在 Google Colab 如何使用代理端口将 Python 服务转发到公网访问



Google Colab是由Google提供的一项免费的云端Jupyter笔记本服务。它允许用户在浏览器中编写和执行Python代码,并且无需进行任何本地安装。Google Colab提供了强大的计算资源,包括GPU和TPU,可用于加速机器学习和数据科学任务。

本篇文章介绍如何在 Colab 中执行 Python Flask 程序,主要完成以下两个目的:

  • Colab 中的 Flask 程序可通过域名公网访问
  • Colab 中的 Flask 程序可访问 Google Drive 中的静态文件

1. 端口转发Colab中运行的Flask程序

Retrieving Secret Values Using REST Services in Infisical

Infisical is the open source secret management platform that developers use to centralize their application configuration and secrets like...