一、背景简介

最近2年,很多公司接项目开始不挑剔了,只要核算下来有收益不会亏,就会库库的做各种没头没脑的项目,都是抱着多撑一天是一天的躺平心态。

如果项目和业务稳定,自然也有动力卷架构卷设计。

然而2024年对于很多研发团队的打工人来说,普遍都是处在随时卷铺盖走人的状态中,自然就是怎么省事怎么来,做项目时间和成本是最重视的维度。

抛开什么AI和各种工具加持,节省编程时间最有效的办法就是:拿现成的,最好只改个端口号。

二、工程结构

2024年上半年各种不大不小的项目写下来,其实从代码工程上看都是差不多的,服务端无非就是前和后两个代码工程,集成基础框架就可以增删改查了。

为了后续其它项目使用相同的基础工程,在第一个项目中,预留了代码工程的初期基础设计,方便那什么循环利用,在这篇文章简单分享一下。

基础的代码工程就这几块,实际上就是前后台两个单体服务,不涉及微服务和复杂架构,就是拿来应付各种奇怪的内部项目的快速开发;两个门面服务分别依赖framesharedthird三层代码包,然后运行启动类即可。

既然是单体服务,自然也不涉及数据库的拆分,能安稳运行就可以了。

<modules>
<!-- 门面管理 -->
<module>bm-facade</module>
<!-- 后台管理 -->
<module>bm-admin</module>
<!-- 业务共享层 -->
<module>bm-shared</module>
<!-- 框架管理 -->
<module>bm-frame</module>
<!-- 第三方接入 -->
<module>bm-third</module>
</modules>

三、模块化功能

3.1 框架模块

主要管理代码工程核心组件依赖,比如SpringBoot框架,MySQL数据库,MybatisPlus持久层,Swagger接口等,并且添加了一个公共过滤器。

@Slf4j
@Component
public class CommonFilter extends OncePerRequestFilter implements Ordered { @Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain)
throws ServletException, IOException { log.info("CommonFilter...doFilterInternal"); // 请求向下转发
chain.doFilter(request, response);
} @Override
public int getOrder() {
return 999 ;
}
}

对于一些必要的配置类和二次封装,也放在了这一层,另外为了简化工程的复杂性,使用AOP的方式包装了日志记录和令牌核验;

AOP切面编程就不说了,这个在项目中经常使用;Token令牌的封装方式可以自行扩展,权限校验拿数据的记录对比一下即可。

@Component
public class BaseToken { @Getter
@Setter
private Long userId; @Getter
@Setter
private String userName; @Getter
@Setter
private String appName; @Getter
@Setter
private Long expireTime; private static final byte[] AES_KEY = Arrays.copyOf(MD5.create().digest(BaseToken.class.getPackage().getName()), 16); @Getter
private final String currentType = BaseToken.class.getTypeName(); public void expireTime(int effective) {
expireTime = System.currentTimeMillis()/1000 + effective ;
} public boolean expired() {
return expireTime < (System.currentTimeMillis() / 1000);
} public String toToken() {
String data = JSONUtil.toJsonStr(this);
return SecureUtil.aes(AES_KEY).encryptBase64(data);
} public static BaseToken parseToken(String token) {
String dataStr = SecureUtil.aes(AES_KEY).decryptStr(token);
return JSONUtil.toBean(dataStr, BaseToken.class);
} public boolean checkPermission (String... permissionCode) {
AuthCheck authService = SpringUtil.getBean(AuthCheck.class);
return authService.hasPermission(this.getUserId(), permissionCode);
} }

使用AOP切面编程拦截要鉴权的方法即可。

@Component
@Aspect
@RequiredArgsConstructor
public class AuthAop { /**
* 切入点
*/
@Pointcut("@annotation(com.butte.mound.frame.security.Auth)")
public void logPointCut() { } @Around("logPointCut()")
public Object around (ProceedingJoinPoint point) throws Throwable {
try{
// 检查权限
checkAuth(point);
// 执行方法
Object result = point.proceed();
return result;
} catch (Exception e){
e.printStackTrace();
throw e ;
}
} private void checkAuth (ProceedingJoinPoint point){
try{
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
Auth auth = method.getAnnotation(Auth.class);
BaseToken token = TokenContext.getToken();
token.checkPermission(auth.authCode());
} catch (Exception e){
e.printStackTrace();
}
}
}

3.2 业务共享模块

主要管理业务代码,数据库相关的持久层文件,如果在服务层前后台业务差异过大的话,也可以考虑分2层管理即可,在体量小的项目中,持久层代码几乎差异不大,最多只是一些自定义查询。

3.3 前后台模块

前后台两个模块,主要就是API接入层,通常就是用户访问和系统管理的两个服务,在逻辑上并没有什么本质差异,为了方便不同角色的请求管理,在两个工程内各添加了一个拦截器。

@Slf4j
@Component
public class FacadeInterceptor implements HandlerInterceptor { @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("req uri : {}",request.getRequestURI()); String facadeToken = "令牌"; BaseToken token = BaseToken.parseToken(facadeToken);
TokenContext.setToken(token); return Boolean.TRUE ;
}
}

3.4 第三方模块

至于常见的第三方API对接,比如短信服务,OSS文件存储,第三方登录等,如果考虑多个项目多次复用的话,可以单独拎一层出来,简单封装一层工具类,方便之后随时替换,当然也可以在业务工程中直接调用第三方的封装类。

四、源码地址

文档仓库:
https://gitee.com/cicadasmile/butte-java-note 源码仓库:
https://gitee.com/cicadasmile/butte-mound

Java轻量级代码工程的更多相关文章

  1. 编写Java脚本统计工程代码总行数

    在新公司工作将近一年了,一直独自一人负责服务端集群的运维和代码的编写.不知不觉从一个Project发展到了七八个Project. 看着越来越多的代码,今天突然想统计一下一共写了多少代码.[这里只统计完 ...

  2. FastDFS搭建及java整合代码【转】

    FastDFS软件介绍 1.什么是FastDFS FastDFS是用C语言编写的一款开源的分布式文件系统.FastDFS为互联网量身定制,充分考虑了冗余备份.负载均衡.线性扩容等机制,并注重高可用.高 ...

  3. java 轻量级同步volatile关键字简介与可见性有序性与synchronized区别 多线程中篇(十二)

    概念 JMM规范解决了线程安全的问题,主要三个方面:原子性.可见性.有序性,借助于synchronized关键字体现,可以有效地保障线程安全(前提是你正确运用) 之前说过,这三个特性并不一定需要全部同 ...

  4. java 从一个工程action 跳转到另外一个工程action

    实现功能:java 从一个工程action 跳转到另外一个工程action 在我们实际编程的过程中,大家一定遇到过这种情况,那就是在一个工程中,需要使用到另外一个工程的实体Bean和方法.那么遇到这种 ...

  5. Scala IDEA for Eclipse里用maven来创建scala和java项目代码环境(图文详解)

    这篇博客 是在Scala IDEA for Eclipse里手动创建scala代码编写环境. Scala IDE for Eclipse的下载.安装和WordCount的初步使用(本地模式和集群模式) ...

  6. pagebean pagetag java 后台代码实现分页 demo 前台标签分页 后台java分页

    java 后台代码实现分页 demo 实力 自己写的 标签分页 package com.cszoc.sockstore.util; import java.util.HashMap;import ja ...

  7. 经典KMP算法C++与Java实现代码

    前言: KMP算法是一种字符串匹配算法,由Knuth,Morris和Pratt同时发现(简称KMP算法).KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的.比 ...

  8. 常用 Java 静态代码分析工具的分析与比较

    常用 Java 静态代码分析工具的分析与比较 简介: 本文首先介绍了静态代码分析的基 本概念及主要技术,随后分别介绍了现有 4 种主流 Java 静态代码分析工具 (Checkstyle,FindBu ...

  9. 分享:根据webservice WSDL地址自动生成java调用代码及JAR包

    分享:根据webservice WSDL地址自动生成java调用代码及JAR包使用步骤:一.安装java 并配置JAVA_HOME 及 path二.安装ANT 并配置ANT_HOME三.解压WsdlT ...

  10. [原创]Java静态代码检查工具介绍

    [原创]Java静态代码检查工具介绍 一  什么是静态代码检查? 静态代码分析是指无需运行被测代码,仅通过分析或检查源程序的语法.结构.过程.接口等来检查程序的正确性,找出代码隐藏的错误和缺陷,如参数 ...

随机推荐

  1. Mybatis【3】-- Mybatis使用工具类读取配置文件以及从属性读取DB信息

    代码直接放在Github仓库[https://github.com/Damaer/Mybatis-Learning ],可直接运行,就不占篇幅了. 1.使用工具类获取sqlSession实例对象 在上 ...

  2. Electron(1) - 快速入门

    1.前言 本节主要讲述Electron的环境搭建以及如何快速创建一个应用 官方文档 2.环境搭建 (1)安装node.js (2)创建项目目录,初始化配置文件 //进入项目目录 并在此目录打开cmd窗 ...

  3. Vue.js vuex

    1.前言 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,它解决了vue中不同组件之间状态共享的问题. 通俗的说,它就是一个带响应式的全局变量管理,它数据的改变会触发相关页面/组件的更 ...

  4. Skyvern – AI浏览器自动化测试工具

    Skyvern – AI浏览器自动化测试工具 ​​ ‍ Skyvern是什么 Skyvern是开源的浏览器自动化工具,结合大型语言模型(LLMs)和计算机视觉技术实现复杂的网页交互和数据提取.与传统的 ...

  5. DataGridView频繁更新PLC报警信息数据源

    1.问题描述 当DataGridView频繁更新数据源时,可能会导致界面闪烁.性能下降等问题.这是因为每次更新数据源时,DataGridView都需要重新绘制和绑定数据,这是一个相对耗时的过程. 2. ...

  6. vue全局事件总线

    首先在main.js中app实例中使用生命周期钩子添加组件 new Vue({ router, render: h => h(App), beforeCreate() { Vue.prototy ...

  7. C++ builder 10.2 x64程序使用typeid获取vcl类名时异常

    C++ builder 10.2 x64程序使用typeid获取vcl类名时异常 比如: const std::type_info &t= typeid(TForm1); 那么t的name() ...

  8. 规模法则(Scaling Law)与参数效率的提高,

    上一篇:<人工智能大语言模型起源篇(三),模型规模与参数效率> 规模法则与效率提高 如果你想了解更多关于提高变换器效率的各种技术,我推荐阅读2020年的<Efficient Tran ...

  9. 一图归纳三大种类矩阵范数:诱导范数,元素范数,Schatten范数,涵盖谱范数,2范数

    转载自:https://blog.csdn.net/qq_27261889/article/details/87902480

  10. StreamJsonRpc.ConnectionLostException 在请求完成之前, 与远程方的 JSON-RPC 连接已丢失

    今天电脑重启之后,发现 visual studio 2022 的智能提示与报错经常性不好用,不光不能在正常时候提示代码错误信息,甚至在编译过后也不提示错误.反复重启,刚开始正常,隔一会儿就会提示什么什 ...