在写业务代码时候,我们经常会在业务层对数据实体进行一些重复的传参,例如更新日期时间。这太麻烦了,为了减轻代码量,我们可以利用AOP和反射对代码进行一些调整,免去这些重复操作。也帮助我们对反射的实际应用有一定认识。
首先自定义一个注解
@Target(ElementType.METHOD)//指定该注解需要加在什么地方,这里设置是加在方法上
@Retention(RetentionPolicy.RUNTIME)//指定该注解保留多久,这里设置是一直保留到jvm加载class文件后仍然保留
public @interface AutoFill {
OperationType value();
}
书写切面类AOP,将注解定义在mapper层方法中,在方法执行之前将参数传入
@Aspect
@Component//一定要记得将AOP加入IOC容器中
@Slf4j
public class AutoFillAspect {
@Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")
public void autoFillPointcut(){};
@Before("autoFillPointcut()")
public void autoFill(JoinPoint joinPoint){
MethodSignature signature = (MethodSignature) joinPoint.getSignature();//Signature中没有getMethod()方法,所以转为子接口去调用
AutoFill annotation = signature.getMethod().getAnnotation(AutoFill.class);
OperationType operationType=annotation.value();
Object[] entity = joinPoint.getArgs();//获取方法的所有参数
if (entity==null || entity.length==0)return;//一般不会出现这个情况
//这里需要说明一点,枚举类在大多数情况下是可以用==替代equals()的,且性能会更好些。
//但需要注意的是,==不会抛出 NullPointerException 异常,且==在编译期间会检测a与b的类型兼容性
if (operationType==OperationType.INSERT){
try {//getDeclaredMethod()和invoke()可能会抛异常
Method setCreateTime = entity[0].getClass().getDeclaredMethod("setCreateTime", LocalDateTime.class);//利用反射获取对象方法,传入方法名和参数类型
Method setUpdateTime = entity[0].getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
setCreateTime.invoke(entity[0], LocalDateTime.now());//利用反射调用entity[0]的setCreateTime方法,传参
setUpdateTime.invoke(entity[0], LocalDateTime.now());
} catch (Exception e) {
e.printStackTrace();
}
} else if (operationType==OperationType.UPDATE) {
try {//getDeclaredMethod()和invoke()可能会抛异常
Method setUpdateTime = entity[0].getClass().getDeclaredMethod("setUpdateTime", LocalDateTime.class);
setUpdateTime.invoke(entity[0], LocalDateTime.now());
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
标签:反射,setUpdateTime,填充,AOP,entity,getDeclaredMethod,LocalDateTime,class From: https://www.cnblogs.com/cyknote/p/17709725.html