springboot自定义注解的使用

目录

  • 背景
  • 分析
  • 代码

背景

 需求:对现有系统中所有数据库表都建立一张对应的备份表;在对主表进行增加,修改,删除操作的同时对备份表进行相同的操作。首先想到的应该是备份一个数据库就完事了~不过实际情况没这么简单,总之需要建立对应的备份表。就比如现在有:A,B,C,D四张表,那就建立A1,B1,C1,D1四张备份表(备份表比主表多一个字段,备份表的主键ID)。在前台对A表进行增删改操作,在A1表中要同步对A表的操作。比如A表新增一条数据,那么A1表要同步新增一条数据;修改,删除操作同样如此。

 现有系统已经实现了对A表的增删改操作,在现有系统上直接修改代码也可以实现。比如在新增的方法中,添加对备份表的新增。在删除的方法新增对备份表的删除,这样也可以实现目的。但是这样做工作量就比较大。

 想一下:增加,修改,删除这3个动作,主表跟备份表是一样的,这就有可能使用注解来解决这种重复的操作。

分析

 先来看一下【增加】动作,伪代码可以写成下面的样子

//主表
public Entity insert(XXVO vo){
	//do something
	....
	xxService.save(entity);
	return entity;
}

 现在要做的就是在这个基础上再给备份表新增一条数据,那么备份表的新增就很简单了


//主表
public Entity insert(XXVO vo){
	//do something
	....
	xxService.save(entity);
	BackupEntity copy = BeanUtil.copy(entity,BackupEntity.class);
	xxBackupService.save(copy)
	return entity;
}

 我们在对备份表新增时做了哪些操作呢?

  • 1.拿到主表的实体对象copy一份,将主表的数据对象copy成备份实体对象
  • 2.用备份表对应的Service对象去保存备份实体数据

如果把这2步操作简化成用注解来完成:

  • 1.要取到主表保存后的entity对象;
  • 2.要知道对应的备份实体是什么类
  • 2.要获取到对应备份表的service对象;

对应的解决办法:

  • 1.可以通过@AfterReturning注解,获取到新增方法的返回值entity对象;
  • 2.在注解上增加属性:backupClass这个值是备份表的实体class对象,在解析注解的时候可以获取到这个属性值来生成对应的备份实体对象
  • 3.在注解上增加backupServiceClass属性;然后通过手动获取spring容器对象的方式来获取备份表的service对象。

代码

实体类

/**
 *
 * 主表
 */
@Data
@TableName("sync_table")
public class SyncTable implements Serializable {

    @TableId(value = "id")
    private String mainId;

    private String f1;

    private String f2;

    private String f3;

    private String f4;
}


/**
 *
 * 备份表
 */
@Data
@TableName("sync_table_backup")
public class SyncTableBackup implements Serializable {

    @TableId(value = "id")
    private String backupId;

    private String mainId;

    private String f1;

    private String f2;

    private String f3;

    private String f4;
}


注解


@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface SyncInsert {

    /**
     * 
     * 备份表实体对象class
     * @return
     */
    Class backupClass();

    /**
     * 
     * 备份表的service对象class
     * @return
     */
    Class backupServiceClass();
}

上面分析的时候提到要手动获取spring容器的对象,那么首先要获取到spring的容器对象ApplicationContext ,通过实现ApplicationContextAware


@Component
public class SpringBeanFactory implements ApplicationContextAware {

	//spring容器
    private ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }


    public ApplicationContext getApplicationContext(){
        return this.applicationContext;
    }
}


解析自定义注解SyncInsert

@Aspect
@Component
public class SyncInsertAspect {


    @Autowired
    SpringBeanFactory beanFactory;
    
    private ApplicationContext getApplicationContext(){
       return  beanFactory.getApplicationContext();
    }

    @AfterReturning(value = "@annotation(com.example.demos.annotaions.SyncInsert)",returning = "entity")
    public void syncInsert(JoinPoint  joinPoint,Object entity){
        MethodSignature signature = (MethodSignature)joinPoint.getSignature();
        SyncInsert syncInsert = signature.getMethod().getAnnotation(SyncInsert.class);
        Class backupServiceClass = syncInsert.backupServiceClass();
        IService backupService = (IService)getApplicationContext().getBean(backupServiceClass);
        Class backupClass = syncInsert.backupClass();
        Object backup = BeanUtil.copyProperties(entity, backupClass);
        backupService.save(backup);
    }






}

修改,删除动作也差不多就不再赘述了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/946906.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

NeurIPS 2024 | 像素级LLM实现图像视频理解、生成、分割和编辑大统一(昆仑万维等)

Accepted by NeurIPS 2024 文章链接:https://arxiv.org/pdf/2412.19806 项目链接:https://vitron-llm.github.io/ Github链接:https://github.com/SkyworkAI/Vitron 亮点直击 首次提出了一种通用的视觉多模态大语言模型(MLLM&…

P8打卡——YOLOv5-C3模块实现天气识别

🍨 本文为🔗365天深度学习训练营中的学习记录博客🍖 原作者:K同学啊 1.检查GPU import torch import torch.nn as nn import torchvision.transforms as transforms import torchvision from torchvision import transforms, dat…

OpenCV-Python实战(16)——单/多模板匹配

一、模板匹配函数 cv2.matchTemplate() result cv2.matchTemplate(image*,templ*,method*,mask*) result&#xff1a;函数返回值&#xff0c;比较结果的数组。 image&#xff1a;原始图像。 templ&#xff1a;模板图像。templ.shape<image.shape。 method&#xff1a;…

分布式 L2 网关下的 OVS 未知单播泛洪

大家读完觉得有意义和帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 目录 1 问题描述 2 基础设施和环境信息 3 故障排除 3.1 确认&#xff1a;单播泛洪 3.2 确认&#xff1a;所有泛洪流量都以 L2 GW 为目标 3.3 验证&#xff1a;容器 ARP 处于活动状态时&…

天猫推荐数据集实践

参考自 https://github.com/xufengtt/recom_teach_code&#xff0c;学习记录。 环境配置&#xff08;maxcomputedataworks&#xff09; 下载天猫推荐数据集&#xff1b;开启 aliyun 的 maxcompute&#xff0c;dataworks&#xff0c;pai&#xff1b;使用 odpscmd 上传本地数据…

库的概念:动态库与静态库

在软件开发中&#xff0c;库是代码复用的核心工具&#xff0c;它帮助开发者避免重复造轮子&#xff0c;提升开发效率。库可以分为动态库和静态库&#xff0c;这两者在程序开发中的使用方式、链接过程和性能上存在显著区别。本文将详细讲解动态库与静态库的定义、区别、链接过程…

Flink源码解析之:如何根据JobGraph生成ExecutionGraph

Flink源码解析之&#xff1a;如何根据JobGraph生成ExecutionGraph 在上一篇Flink源码解析中&#xff0c;我们介绍了Flink如何根据StreamGraph生成JobGraph的流程&#xff0c;并着重分析了其算子链的合并过程和JobGraph的构造流程。 对于StreamGraph和JobGraph的生成来说&…

风力涡轮机缺陷检测数据集,91.4%准确识别率,18912张图片,支持yolo,PASICAL VOC XML,COCO JSON格式的标注

风力涡轮机缺陷检测数据集&#xff0c;91.4&#xff05;准确识别率&#xff0c;18912张图片&#xff0c;支持yolo&#xff0c;PASICAL VOC XML&#xff0c;COCO JSON格式的标注 数据集下载&#xff1a; &#xff59;&#xff4f;&#xff4c;&#xff4f; &#xff56;&#…

系统设计——大文件传输方案设计

摘要 大文件传输是指通过网络将体积较大的文件从一个位置发送到另一个位置的过程。这些文件可能包括高清视频、大型数据库、复杂的软件安装包等&#xff0c;它们的大小通常超过几百兆字节&#xff08;MB&#xff09;甚至达到几个吉字节&#xff08;GB&#xff09;或更大。大文…

linux中执行命令

1.1 命令格式 命令格式&#xff1a; 主命令 选项 参数&#xff08;操作对象&#xff09; 命令分为两类&#xff1a; 内置命令&#xff08; builtin &#xff09;&#xff1a;由 shell 程序自带的命令 外部命令&#xff1a;有独立的可执行程序文件&#xff0c;文件名即命令…

Elasticsearch:当混合搜索真正发挥作用时

作者&#xff1a;来自 Elastic Gustavo Llermaly 展示混合搜索何时优于单独的词汇或语义搜索。 在本文中&#xff0c;我们将通过示例探讨混合搜索&#xff0c;并展示它与单独使用词汇或语义搜索技术相比的真正优势。 什么是混合搜索&#xff1f; 混合搜索是一种结合了不同搜索…

Python pyside6 设置的一个《广告图片生成器》

一、图&#xff1a; 二、说明书&#xff1a; 广告图片生成器使用说明 软件功能 这是一个用于生成广告图片的工具&#xff0c;可以快速制作包含产品图片和文字的广告图片。 主要特点 自定义广告尺寸&#xff08;默认620420像素&#xff09; 智能去除产品图片背景 自动排版&…

Spark基本介绍

一&#xff0c;Spark是什么 1.定义&#xff1a;Aache Spark是用于大规模数据处理的统一分析引擎。 二&#xff0c;Spark的发展 三&#xff0c;Spark的特点 高效性 计算速度快 提供了一个全新的数据结构RDD&#xff08;弹性分布式数据集&#xff09;。整个计算操作&#xff0c;…

Elasticsearch操作笔记版

文章目录 1.ES索引库操作(CRUD)1.mapping常见属性(前提)2.创建索引库3.查询&#xff0c;删除索引库4.修改索引库 2.ES文档操作(CRUD)1.新增文档2.查询、删除文档查询返回的数据解读&#xff1a; 3.修改文档 3.RestClient操作(索引库/文档)(CRUD)1.什么是RestClient2.需要考虑前…

EFEVD: Enhanced Feature Extraction for Smart Contract Vulnerability Detection

假设&#xff0c;攻击者在合约 Dao 内存放有 1 Ether 攻击者调用 withdraw 函数&#xff0c;提取 1 Ether&#xff1b; 函数执行到 require 之后&#xff0c; balances 之前时&#xff0c;6789-6789-6789- contract Dao {function withdraw() public {require(balances[msg.…

我的线代观-秩(向量,矩阵)

都说秩是线代中不可避免的一环&#xff0c;当然&#xff0c;它其中最重要的一环。 我在学习线代之后&#xff0c;也有这种感受&#xff0c;它有着一种很绕的感受。 1.矩阵中 在矩阵中&#xff0c;它的秩是怎么定义的呢。它常常与行列式扯上关系&#xff0c;我们拿三阶矩阵为例…

ES IK分词字典热更新

前言 在使用IK分词器的时候&#xff0c;发现官方默认的分词不满足我们的需求&#xff0c;那么有没有方法可以自定义字典呢&#xff1f; 官方提供了三种方式 一、ik本地文件读取方式 k插件本来已为用户提供自定义词典扩展功能&#xff0c;只要修改配给文件即可&#xff1a; …

基于Spring Boot的电影网站系统

一、技术架构 后端框架&#xff1a;Spring Boot&#xff0c;它提供了自动配置、简化依赖管理、内嵌式容器等特性&#xff0c;使得开发者可以快速搭建起一个功能完备的Web应用。 前端技术&#xff1a;可能采用Vue.js、JS、jQuery、Ajax等技术&#xff0c;结合Element UI等组件库…

C#运动控制系统:雷赛控制卡实用完整例子 C#雷赛开发快速入门 C#雷赛运动控制系统实战例子 C#快速开发雷赛控制卡

雷赛控制技术 DMC系列运动控制卡是一款新型的 PCI/PCIe 总线运动控制卡。可以控制多个步进电机或数字式伺服电机&#xff1b;适合于多轴点位运动、插补运动、轨迹规划、手轮控制、编码器位置检测、IO 控制、位置比较、位置锁存等功能的应用。 DMC3000 系列卡的运动控制函数库功…

android studio 写一个小计时器(版本二)

as版本&#xff1a;23.3.1patch2 例程&#xff1a;timer 在前一个版本的基本上改的&#xff0c;增加了继续的功能&#xff0c;实现方法稍微不同。 动画演示&#xff1a; activity_main.xml <?xml version"1.0" encoding"utf-8"?> <androidx…