首页 > 编程语言 >Java 切入点 JoinPoint的使用,用于拦截方法,与自定义注解

Java 切入点 JoinPoint的使用,用于拦截方法,与自定义注解

时间:2024-03-05 18:56:47浏览次数:24  
标签:SET Java 自定义 class JoinPoint UPDATE entity AutoFillConstant public

这里的代码案例是外卖系统中,用于统一修改新增和更新内容中的更新时间与更新人内容,根据具体情况,在使用时进行自定义修改就行了

第一部分是annotation的,因为是为了自动填充数据准备,所以创建annotation包后,在其中创建了 AutoFill 的注解类型

/**
* 自定义注解,用于标识某个方法需要用于功能字段自动填充处理
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoFill {
// 数据库操作类型: UPDATE | INSERT
OperationType value();
}

 

第二部分是aspect的,其中需要注意的点如下:

1、需要注意获取方法引用的是 import java.lang.reflect.Method; 别引用错了会报错

2、OperationType 是数据库操作类型的一个公共枚举项(最后会附上内容)

3、AutoFillConstant 是公共字段自动填充的常量类(最后会附上内容)

4、BaseContext 是用于存放修改人/创建人 id的,在登录校验中存入信息(最后会附上内容)

/**
* 自定义切面类,实现公共字段自动填充处理逻辑
*/
@Aspect
@Component
@Slf4j
public class AutoFillAspect {

/**
* 切入点,就是对哪些类,哪些方法进行拦截
* 切点表达式 : 拦截了 mapper包中所有的类和所有的方法 且引入自定义注解,还需要有 AutoFill注解标识
*/
@Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
public void autoFillPointCut() {
}

/**
* 前置通知
* 直接引用之前定义好的切入点
* 在该通知中进行公共字段的赋值
*/
@Before("autoFillPointCut()")
public void autoFill(JoinPoint joinPoint) {
log.info("开始进行公共字段的填充");

// 获取被拦截的,当前数据库操作的类型,判断是 UPDATE还是 INSERT
MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 获得方法前面对象
AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);// 获得方法上的注解对象
OperationType operationType = autoFill.value(); // 获得数据库操作类型

// 获取当前被拦截的方法的参数-->实体对象
Object[] pointArgs = joinPoint.getArgs();
if (pointArgs == null || pointArgs.length == 0) {
return;
}

Object entity = pointArgs[0];

// 准备赋值的数据
LocalDateTime now = LocalDateTime.now();
Long currentId = BaseContext.getCurrentId();

// 根据当前操作的类型,为对应的属性通过反射来赋值
if (operationType.equals(OperationType.INSERT)) {
// 为 4个公共字段赋值
// 获得set方法来赋值
try {
Method setCreateTime = entity
.getClass()
.getDeclaredMethod(AutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
Method setCreateUser = entity
.getClass()
.getDeclaredMethod(AutoFillConstant.SET_CREATE_USER, Long.class);
Method setUpdateTime = entity
.getClass()
.getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
Method setUpdateUser = entity
.getClass()
.getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);

// 通过反射来为对象属性赋值
setCreateTime.invoke(entity, now);
setCreateUser.invoke(entity, currentId);
setUpdateTime.invoke(entity, now);
setUpdateUser.invoke(entity, currentId);
} catch (Exception ex) {
log.info(ex.getMessage());
}
} else {
// 为 2个字段赋值
try {
Method setUpdateTime = entity
.getClass()
.getDeclaredMethod(AutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
Method setUpdateUser = entity
.getClass()
.getDeclaredMethod(AutoFillConstant.SET_UPDATE_USER, Long.class);

// 通过反射来为对象属性赋值
setUpdateTime.invoke(entity, now);
setUpdateUser.invoke(entity, currentId);
} catch (Exception ex) {
log.info(ex.getMessage());
}
}
}



}





 

OperationType 

public enum OperationType {

/**
* 更新操作
*/
UPDATE,

/**
* 插入操作
*/
INSERT

}


AutoFillConstant

public class AutoFillConstant {
    /**
* 实体类中的方法名称
*/
public static final String SET_CREATE_TIME = "setCreateTime";
public static final String SET_UPDATE_TIME = "setUpdateTime";
public static final String SET_CREATE_USER = "setCreateUser";
public static final String SET_UPDATE_USER = "setUpdateUser";
}
 

BaseContext

public class BaseContext {

public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();

public static void setCurrentId(Long id) {
threadLocal.set(id);
}

public static Long getCurrentId() {
return threadLocal.get();
}

public static void removeCurrentId() {
threadLocal.remove();
}

}
 

标签:SET,Java,自定义,class,JoinPoint,UPDATE,entity,AutoFillConstant,public
From: https://www.cnblogs.com/Lee597/p/18054647

相关文章

  • Java 读取命令行输入
    在Java中,您可以使用Scanner类从命令行读取输入。这个类属于java.util包,因此在使用之前您需要导入该包。下面是一个如何从命令行读取输入的Java程序示例:importjava.util.Scanner;//导入Scanner类publicclassMain{publicstaticvoidmain(String[]args)......
  • java.lang.reflect.InaccessibleObjectException
    低版本springboot应用使用高版本JDK报以下异常:Causedby:java.lang.reflect.InaccessibleObjectException:Unabletomakeprotectedfinaljava.lang.Classjava.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain)throwsjava......
  • 自定义Hooks:四个典型的使用场景
    一、如何用好hook要用好ReactHooks,很重要的一点,就是要能够从Hooks的角度去思考问题。要做到这一点其实也不难,就是在遇到一个功能开发的需求时,首先问自己一个问题:这个功能中的哪些逻辑可以抽出来成为独立的Hooks?这样问的目的,是为了让我们尽可能的吧业务陆奥及拆分......
  • JAVA私有构造函数---java笔记
    在Java中,构造函数是一种特殊的方法,它用于初始化新创建的对象。当我们创建一个类的实例时,构造函数会自动被调用。构造函数可以有不同的访问修饰符,如public、protected、default(即包级私有)和private。其中,private构造函数是Java中一种特殊的构造函数。私有构造函数(PrivateConstru......
  • 3月5日-java随笔(雪花算法)
    一、简单介绍一下雪花算法原理1、雪花算法生成一个64bit的长整型标识符,其内部结构包含四个部分。首先,最左侧的一个bit通常被置为0作为符号位(在实际应用中往往无意义)。接下来的41bit用于存储自某个时间起点以来的毫秒级时间戳,以此确保生成的ID具有时间上的有序性。第三个组成部分......
  • Java八股文
    什么是面向对象对比面向过程注重事情的步骤顺序,面向对象更关注有哪些参与者(对象),各种需要做什么,易于扩展。封装内部对外部来说是透明的,无需修改关心内部实现例如:操作数据库,不需要关心连接简历,sql执行,引入mybatis,调方法即可JavaBean属性私有,不能由外部随意修改。继承继承基......
  • 基于JAVA的2048小游戏的二次开发
    引言《2048Numberpuzzlegame》是一款数字益智游戏,而《2048》的初始数字则是由2+2组成的基数4。在操作方面的不同则表现为一步一格的移动,变成更为爽快的一次到底。相同数字的方框在靠拢、相撞时会相加。系统给予的数字方块不是2就是4,玩家要想办法在这小小的16格范围中凑出「2048」......
  • 基于JAVA的康威生命游戏二次开发
    引言:       康威生命游戏(Conway'sGameofLife)是一种基于细胞自动机的零玩家游戏,由数学家约翰·康威(JohnConway)于1970年创建。这个游戏并不是传统意义上的游戏,而是一种模拟生命演变的规则系统。康威生命游戏的“宇宙”是一个由无限的二维网格组成的平面,每个格子被称为......
  • Vue学习笔记32--自定义指令--对象式
    Vue学习笔记32--自定义指令--对象式总结:1.autofocus属性,用于input自动获取焦点2.directives指令中this是指window3.vm中使用directives进行自定义指令,为局部指令4.全局指令和全局过滤器类似,应在vm之外使用directive进行声明使用自定义指令总结: 定......
  • linux下的java部署
    jar命令简介java部署jar包可以使用java-jar命令,比如:java-jardemo.jar执行上述命令后,JAR包中的程序将在Linux系统中运行。注:在运行JAR包之前,确保你的JAR文件是可执行的,并且包含了正确的类和依赖项。如果JAR包依赖于其他库或配置文件,确保它们也在正确的位置可用。......