JAVA设计模式:注解+模板+接口
1.基础组件
1.1注解类控制代码执行启动、停止、顺序
/*** @author : test* @description : 数据同步注解* @date : 2025/4/18*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SyncMeta {/*** 执行服务名称* @return*/String name() default "";/*** 是否启用** @return*/boolean isEnable() default false;/*** 顺序* @return*/int order() default 0;}
1.2数据获取基类
1.2.1数据获取基类接口(interface)
/*** @author : test* @description :* @date : 2025/4/18*/
public interface BaseDataAcquisition { /*** 获取第三方数据*/void acquire();
}
1.2.2数据获取基类抽象类(abstract)实现接口
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/*** @author : test* @description :* @date : 2025/4/18*/
@Slf4j
public class BaseDataAcquisitionImpl<M extends BaseMapper<T>, T> implements BaseDataAcquisition {@Autowiredprotected M baseMapper;@Autowiredprotected SyncUrlProperties syncUrlProperties;@Resourceprotected ThirdDatabaseMapper thirdDatabaseMapper;@Overridepublic void acquire() {acquireData(DataSouceEnum.DATASOURCE);}/*** 数据来源方式*/protected void acquireData(DataSouceEnum dataSouceEnum) {List<T> allData = new ArrayList<>();switch (dataSouceEnum) {case DATASOURCE:allData = getThirdDataFromDB();break;case INTERFACE:allData = getDataFromUrl();break;default:break;}if (CollUtil.isEmpty(allData)) {log.error("采集数据为空,请确认数据采集方式");return;}//数据抽取,新增addExtraData(allData);//数据处理dealData(allData);//集合切分,数据批处理List<List<T>> parts = Lists.partition(allData, 1000);parts.stream().forEach(list -> saveOrUpdate(list));//数据抽取处理extraDeal();}/*** 用来重写** @return*/protected List<T> getThirdDataFromDB() {return null;}/*** 用来重写** @return*/protected List<T> getDataFromUrl() {return covert(null);}/*** 用来重写* 数据保存和更新* @param part*/protected void saveOrUpdate(List<T> part) {}/*** 用来重写* 数据转换* @param body*/protected List<T> covert(String body) {List<T> allData = new ArrayList<>();return allData;}/*** 用来重写* 新增抽取数据* @param allData*/protected void addExtraData(List<T> allData) {}/*** 用来重写* 数据处理* @param allData*/protected void dealData(List<T> allData) {}/*** 用来重写* 抽取数据处理* @param allData*/protected void extraDeal() {}}
2.数据抽取实现
2.1人员数据抽取示例
@Service
@SyncMeta(name = Constants.PERSON_SERVICE, isEnable = false, order = 2)
@Slf4j
public class PersonDataAcquisitionImpl extends BaseDataAcquisitionImpl<ThirdPersonMapper, ThirdPerson>{/*** 三方数据获取*/@Overrideprotected List getThirdDataFromDB() {return thirdDatabaseMapper.getAllThirdPerson();}@Overrideprotected List getDataFromUrl() {String url = syncUrlProperties.getPersonUrl();String body = HttpRequest.get(url).timeout(3000)//.body(new JSONObject()) get请求发送body会报错,post请求需放开注释.execute().body();return covert(body);}@Overrideprotected void saveOrUpdate(List part) {this.baseMapper.batchSaveOrUpdate(part);}@Overrideprotected List covert(String body) {List<ThirdPerson> thirdPeople = new ArrayList<>();//todo 转换请求结果return thirdPeople;}
}
2.2组织数据抽取示例
/*** @author : test* @description :* @date : 2025/4/18*/
@Service
@SyncMeta(name = Constants.ORG_SERVICE, isEnable = false, order = 1)
@Slf4j
public class OrgDataAcquisitionImpl extends BaseDataAcquisitionImpl<ThirdOrgMapper, ThirdOrg> {@Autowiredprivate ThirdRedisOrgCache thirdRedisOrgCache;/*** 数据库方式获取数据*/@Overrideprotected List<ThirdOrg> getThirdDataFromDB() {return thirdDatabaseMapper.getAllThirdOrg();}/*** url方式获取数据*/@Overrideprotected List<ThirdOrg> getDataFromUrl() {String url = syncUrlProperties.getOrgUrl();String body = HttpRequest.get(url).timeout(5000)//.body(new JSONObject()) get请求发送body会报错,post请求需放开注释.execute().body();return covert(body);}/*** 数据更新或保存*/@Overrideprotected void saveOrUpdate(List<ThirdOrg> part) {this.baseMapper.batchSaveOrUpdate(part);}/*** 数据转换*/@Overrideprotected List<ThirdOrg> covert(String body) {List<ThirdOrg> thirdOrgs = new ArrayList<>();//todo 转换请求结果return thirdOrgs;}/*** 数据新增*/@Overrideprotected void addExtraData(List<ThirdOrg> allData) {ThirdOrg thirdOrg = new ThirdOrg();thirdOrg.setName(Constants.NO_ORG_NAME_NAME);thirdOrg.setThirdCode(Constants.NO_ORG_NAME_CODE);thirdOrg.setType(0);allData.add(thirdOrg);}/*** 数据处理*/@Overrideprotected void extraDeal() {thirdRedisOrgCache.initData();}
}
2.3 mybatis 数据批量新增更新操作
<insert id="batchSaveOrUpdate">insert into third_person(NAME, CODE, SEX, PHONE, CARD_NUMBER, ID_CARD, EMAIL, ENTRY_DATE, CAR_NUMBER, THIRD_ORG_CODE, THIRD_DORM_CODE, TYPE)values<foreach collection="pojoList" item="item" index="index" separator=",">(#{item.name},#{item.code},#{item.sex},#{item.phone},#{item.cardNumber},#{item.idCard},#{item.email},#{item.entryDate},#{item.carNumber},#{item.thirdOrgCode},#{item.thirdDormCode},#{item.type})</foreach>ON DUPLICATE KEY UPDATENAME = values(NAME),SEX = values(SEX),PHONE = values(PHONE),CARD_NUMBER = values(CARD_NUMBER),EMAIL = values(EMAIL),ID_CARD = values(ID_CARD),ENTRY_DATE = values(ENTRY_DATE),THIRD_ORG_CODE = values(THIRD_ORG_CODE),THIRD_DORM_CODE = values(THIRD_DORM_CODE),TYPE = values(TYPE),UPDATE_TIME = now()</insert>
3.数据抽取触发
/**** @author : test* @description :* @date : 2025/4/18*/
@Service
public class DataAcquisitionStrategy {public void process(List<String> serviceNames) {Map<String, BaseDataAcquisition> allServiceMap = AppContextHelper.getContext().getBeansOfType(BaseDataAcquisition.class);List<BaseDataAcquisition> allAcquisitionService = allServiceMap.values().stream().collect(Collectors.toList());List<BaseDataAcquisition> processServices = allAcquisitionService.stream().filter(service -> {SyncMeta syncMeta = service.getClass().getAnnotation(SyncMeta.class);if (CollUtil.isNotEmpty(serviceNames)) {return syncMeta != null && syncMeta.isEnable() && serviceNames.contains(syncMeta.name());} else {return syncMeta != null && syncMeta.isEnable();}}).collect(Collectors.toList());TreeMap<Integer, BaseDataAcquisition> sortedMap = new TreeMap<>();processServices.forEach(service->{SyncMeta syncMeta = service.getClass().getAnnotation(SyncMeta.class);sortedMap.put(syncMeta.order(), service);});sortedMap.values().forEach(service-> service.acquire());}}
相关文章:
JAVA设计模式:注解+模板+接口
1.基础组件 1.1注解类控制代码执行启动、停止、顺序 /*** author : test* description : 数据同步注解* date : 2025/4/18*/ Target({ElementType.TYPE}) Retention(RetentionPolicy.RUNTIME) Documented public interface SyncMeta {/*** 执行服务名称* return*/String name…...
Linux系统编程 day6 进程间通信mmap
父子共享的信息:文件描述符,mmap建立的共享映射区(MAP_SHARED) mmap父子间进程通信 var的时候 :读时共享,写时复制 父进程先创建映射区,指定共享MAP_SHARED权限 , fork创建子进程…...
【MySQL】MySQL建立索引不知道注意什么?
基本原则: 1.选择性原则: 选择高选择性的列建立索引(该列有大量不同的值) 2.适度原则:不是越多越好,每个索引都会增加写入开销 列选择注意事项: 1.常用查询条件列:WHERE字句中频繁使用的列 2.连接操作列…...
定制一款国密浏览器(9):SM4 对称加密算法
上一章介绍了 SM3 算法的移植要点,本章介绍对称加密算法 SM4 的移植要点。 SM4 算法相对 SM3 算法来说复杂一些,但还是比较简单的算法,详细算法说明参考《GMT 0002-2012 SM4分组密码算法》这份文档。铜锁开源项目的实现代码在 sm4.c 文件中,直接拿过来编译就可以。 但需要…...
Redis 的持久化机制(RDB, AOF)对微服务的数据一致性和恢复性有何影响?如何选择?
Redis 的持久化机制(RDB 和 AOF)对于保证 Redis 服务重启或崩溃后数据的恢复至关重要,这直接影响到依赖 Redis 的微服务的数据一致性和恢复能力。 1. RDB (Redis Database Backup) 机制: 在指定的时间间隔内,将 Redis 在内存中的…...
lottie深入玩法
A、json文件和图片资源分开 delete 是json资源名字 /res/lottie/delete_anim_images是图片资源文件夹路径 JSON 中引用的图片名,必须与实际图片文件名一致 B、json文件和图片资源分开,并且图片加载不固定 比如我有7张图片,分别命名1~7&…...
Android学习总结之算法篇七(图和矩阵)
有向图的深度优先搜索(DFS)和广度优先搜索(BFS)的示例,以此来模拟遍历 GC Root 引用链这种有向图结构: 一、深度优先搜索(DFS) import java.util.*;public class GraphDFS {privat…...
docker 大模型
使用 Docker 实现大模型的步骤指南 在今天的文章中,我们将指导刚入行的小白如何使用 Docker 来运行大模型。Docker 是一个开放源代码的平台,允许开发者自动化应用程序的部署、扩展和管理。通过将大模型放入 Docker 容器中,我们可以确保其在各…...
热门与冷门并存,25西电—电子工程学院(考研录取情况)
1、电子工程学院各个方向 2、电子工程学院近三年复试分数线对比 学长、学姐分析 由表可看出: 1、电子科学与技术25年相较于24年上升20分 2、信息与通信工程、控制科学与工程、新一代电子信息技术(专硕)25年相较于24年下降25分 3、25vs24推…...
Warcraft Logs [Classic] [WCL] BOSS ID query
Warcraft Logs [Classic] [WCL] BOSS ID query 所有副本BOSSID查询 https://wowpedia.fandom.com/wiki/DungeonEncounterID#Retail IDNameMapInstanceIDPatch227High Interrogator GerstahnBlackrock Depths230228Lord RoccorBlackrock Depths230229Houndmaster GrebmarBlackro…...
python录屏工具实现
python录屏工具实现 实现一 按Ctrl+Shift+8开始录制,按Ctrl+Shift+9结束录制,视频保存到“ d:\录屏视频”目录中。 先看用了哪些库 import cv2: 引入 OpenCV 库,这是一个开源计算机视觉库,用于图像和视频处理。在这个程序中,它用于创建视频文件、处理图像等。需要安装ope…...
架构师面试(三十一):IM 消息收发逻辑
问题 今天聊一下 IM 系统最核心的业务逻辑。 在上一篇短文《架构师面试(三十):IM 分层架构》中详细分析过,IM 水平分层架构包括:【入口网关层】、【业务逻辑层】、【路由层】和【数据访问层】;除此之外&a…...
基于若依框架前后端分离的项目部署
文章目录 单项目的部署项目目录后端打包上传前端打包上传配置nginx服务器打开防火墙完成 两个项目的部署两个项目介绍后端打包并上传前端打包并上传nginx配置服务器端口开放完成 腾讯云服务器 之 环境搭建 单项目的部署 项目目录 后端打包上传 查看端口号 在ruoyi-admin的appl…...
黑马Java基础笔记-1
JVM,JDK和JRE JDK是java的开发环境 JVM虚拟机:Java程序运行的地方 核心类库:Java已经写好的东西,我们可以直接用。 System.out.print中的这些方法就是核心库中的所包含的 开发工具: javac(编译工具)、java&…...
面向新一代扩展现实(XR)应用的物联网框架
中文标题: 面向新一代扩展现实(XR)应用的物联网框架 英文标题: Towards an IoT Framework for the New Generation of XR Applications 作者信息 Joo A. Dias,UNIDCOM - IADE,欧洲大学,里斯本&…...
pcl各模块
参考资料: https://github.com/Ewenwan/MVision/blob/master/PCL_APP/1_%E7%82%B9%E4%BA%91%E6%BB%A4%E6%B3%A2filter.md 点云库PCL各模块学习 语雀 各模块依赖关系: 模块: common pcl_common中主要是包含了PCL库常用的公共数据结构和方…...
Oracle Recovery Tools修复ORA-600 6101/kdxlin:psno out of range故障
数据库异常断电,然后启动异常,我接手该库,尝试recover恢复 SQL> recover database; ORA-10562: Error occurred while applying redo to data block (file# 2, block# 63710) ORA-10564: tablespace SYSAUX ORA-01110: ???????? 2: H:\TEMP\GDLISNET\SYSAUX01.DBF O…...
Python网络编程从入门到精通:Socket核心技术+TCP/UDP实战详解
引言 网络编程是构建现代分布式系统的核心能力,而Socket作为通信的基石,其重要性不言而喻。本文将从零开始,通过清晰的代码示例、原理剖析和对比分析,带你彻底掌握Python中的Socket编程技术,涵盖TCP可靠连接、UDP高效…...
2025MathorcupC题 音频文件的高质量读写与去噪优化 保姆级教程讲解|模型讲解
2025Mathorcup数学建模挑战赛(妈妈杯)C题保姆级分析完整思路代码数据教学 C题:音频文件的高质量读写与去噪优化 随着数字媒体技术的迅速发展,音频处理成为信息时代的关键技术之一。在日常生活中,从录音设备捕捉的原始…...
.net core web api 数据验证(DataAnnotations)
目录 一、什么是 DataAnnotations? 二、扩展验证逻辑(自定义验证器) 一、什么是 DataAnnotations? DataAnnotations 是一组特性(Attributes),用于在模型类上定义验证规则。主要用于属性级别的…...
【工具-Krillin AI】视频翻译、配音、语音克隆于一体的一站式视频多语言转换工具~
Krillin AI 是全能型音视频本地化与增强解决工具。这款简约而强大的工具,集音视频翻译、配音、语音克隆于一身,支持横竖屏格式输出,确保在所有主流平台(哔哩哔哩,小红书,抖音,视频号,…...
ICPR-2025 | 让机器人在未知环境中 “听懂” 指令精准导航!VLTNet:基于视觉语言推理的零样本目标导航
作者:Congcong Wen, Yisiyuan Huang, Hao Huang ,Yanjia Huang, Shuaihang Yuan, YuHao, HuiLin and Yi Fang 单位:纽约大学阿布扎比分校具身人工智能与机器人实验室,纽约大学阿布扎比分校人工智能与机器人中心,纽约大学坦登工程…...
Shiro-550 动调分析与密钥正确性判断
一、Shiro 简介 Apache Shiro是一个开源安全框架,用于构建 Java 应用程序,提供身份验证、授权、加密和会话管理等功能。 二、Shiro-550(CVE-2016-4437) 1、漏洞原理 Shiro 在用户登陆时提供可选项 RememberMe,若勾选…...
Python制作简易PDF查看工具PDFViewerV1.0查找功能优化
原文说明 为不破坏原文结构,因此功能优化不在原文中维护了。关于这款工具原文请通过下面链接访问。Python制作简易PDF查看工具PDFViewerV1.0 这款小工具基本功能已经可以作为一款文档浏览器使用,但还有一些美中不足的地方,本文将介绍对文本查…...
20250419将405的机芯由4LANE的LVDS OUT配置为8LANE的步骤
20250419将405的机芯由4LANE的LVDS OUT配置为8LANE的步骤 2025/4/19 15:38 查询格式YUV/RGB 81 09 04 24 60 FF 90 50 00 00 FF 查询辨率帧率 81 09 04 24 72 FF 90 50 01 03 FF 查询LVDS mode : Singel output/Dual output 81 09 04 24 74 FF 90 50 00 00 FF 配置405的机…...
从0开发一个unibest+vue3项目,使用vscode编辑器开发,总结vue2升vue3项目开始,小白前期遇到的问题
开头运行可看官网 链接: unibest官网 一:vscode中vue3代码显示报错标红波浪线 去查看扩展商店发现一些插件都弃用了,例如h5的插件以及vue老插件 解决办法:下载Vue - Official插件(注意:横杠两边是要加空格的ÿ…...
Jinja2模板引擎SSTI漏洞
1. 引入 再研究大模型相关应用的漏洞CVE-2025-25362时(参考1),看到作者给了比较详细的分析(参考2)。下面对这个漏洞做个介绍。 2. 漏洞类型 这个漏洞属于CWE-1336,它主要关注在使用模板引擎进行脚本化处…...
HTML5好看的水果蔬菜在线商城网站源码系列模板4
文章目录 1.设计来源1.1 主界面1.2 关于我们1.3 商品信息1.4 新闻资讯1.5 联系我们1.5 登录注册 2.效果和源码2.1 动态效果2.2 源代码 源码下载 作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/147264262 HTML5好看的水果…...
Python语法系列博客 · 第6期[特殊字符] 文件读写与文本处理基础
上一期小练习解答(第5期回顾) ✅ 练习1:字符串反转模块 string_tools.py # string_tools.py def reverse_string(s):return s[::-1]调用: import string_tools print(string_tools.reverse_string("Hello")) # 输出…...
多人五子棋联机对战平台 测试报告
目录 项目介绍 测试用例设计 部分功能测试示例 自动化测试 测试范围 排除范围 自动化测试目录编辑 执行全部自动化测试用例 性能说明 总结 性能测试 结果分析 测试总结 项目介绍 该项目基于WebSocket实现实时通信,采用SSM框架构建在线五子棋多人联机…...
