Java Spring 通过 AOP 实现方法参数的重新赋值、修改方法参数的取值
AOP 依赖
我创建的项目项目为 SpringBoot 项目
org.springframework.boot
spring-boot-starter-parent
3.1.3
org.springframework.boot
spring-boot-starter-aop
String 类型参数
这里以对前端传递过来的加密数据进行解密为例
注解
import java.lang.annotation.*;
/**
* 标注需要进行 RSA 加密算法解密的通用注解。
* 该注解可以使用在类上、方法上、方法参数上、字段/属性上、局部变量上
*/
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DecodeRsaCommonAnnotation {
}
import java.lang.annotation.*;
/**
* 标注需要进行 RSA 加密算法解密的方法参数的注解。
* 该注解可以使用在方法参数上
*/
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DecodeRsaParameterAnnotation {
}
控制器方法
@GetMapping("/test")
@DecodeRsaCommonAnnotation
public void test(
@DecodeRsaParameterAnnotation
String text
) {
System.out.println(text);
}
方式一:通过环绕通知实现 [个人比较推荐]
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Aspect
@Order(1)
@Component
public class DecodeRsaAspect {
/**
* DecodeRsaAspect 的切点为被 @DecodeRsaCommonAnnotation 标记的位置
*/
@Pointcut("@annotation(cn.org.xiaoweiba.graduationdesign.bookmall.annotation.rsa.DecodeRsaCommonAnnotation)")
public void pointCut() {
}
/**
* 采用 Rsa 加密算法进行解密
*
* @param proceedingJoinPoint 切点
*/
@Around("pointCut()")
public Object decodeRsaAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
Object returnVal = null;
try {
// 获取切点方法的参数
Object[] args = proceedingJoinPoint.getArgs();
// 中间处理 ...
// 对切点方法的参数进行重新赋值
for (int i = 0; i
方式二:通过前置通知 + 反射实现
Java ReflectUtil 反射相关的工具类
由于 JDK 8 中有关反射相关的功能自从 JDK 9 开始就已经被限制了,如:通过反射修改 String 类型变量的 value 字段(final byte[]),所以要能够使用运行此方法,需要在运行项目时,添加虚拟机(VM)选项:--add-opens java.base/java.lang=ALL-UNNAMED,开启默认不被允许的行为
通过反射修改 String 类型对象 value 取值的工具方法
获取指定对象中的指定字段(不包含父类中的字段)
/**
* 获取指定对象中的指定字段(不包含父类中的字段)。
* 此方法在获取指定对象中的指定字段时,会包证获取的指定字段能够被访问。
*
* @param object 要获取字段的指定对象
* @param fieldName 要获取的指定字段的名称
* @return 指定对象中的指定字段
*/
public static Field getField(Object object, String fieldName) throws NoSuchFieldException {
// 获取指定对象的 Class
Class objectClass = object.getClass();
// 获取指定对象中的指定字段
Field declaredField = objectClass.getDeclaredField(fieldName);
// 保证获取的指定字段能够被访问
declaredField.setAccessible(true);
return declaredField;
}
通过反射为字符串对象的 value 字段重新赋值为 strValue
/**
* 通过反射为字符串对象的 value 字段重新赋值为 strValue,
* 从而保证不修改字符串对象的引用,并且能够修改字符串的取值
* 由于 JDK 8 中有关反射相关的功能自从 JDK 9 开始就已经被限制了,所以要能够使用运行此方法,
* 需要在运行项目时,添加虚拟机(VM)选项:--add-opens java.base/java.lang=ALL-UNNAMED
* 开启默认不被允许的行为
*
* @param str 需要进行重新赋值的字符串对象
* @param strValue 要赋值给字符串对象的值
*/
public static void setValueString(String str, String strValue) throws NoSuchFieldException, IllegalAccessException {
// 获取字符串的 value 字段
Field strValueField = getField(str, "value");
// 为字符串对象的 value 字段重新赋值
// strValueField.set(str, strValue.getBytes(StandardCharsets.UTF_8)); 不要使用该种方法,会出现乱码
// 采用如下方式,获取 strValue 的 value 字段值,将其赋值给 str 的 value 字段
strValueField.set(str, strValueField.get(strValue));
}
切面类
import cn.org.xiaoweiba.graduationdesign.bookmall.utils.ReflectUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Aspect
@Order(1)
@Component
public class DecodeRsaAspect {
/**
* DecodeRsaAspect 的切点为被 @DecodeRsaCommonAnnotation 标记的位置
*/
@Pointcut("@annotation(cn.org.xiaoweiba.graduationdesign.bookmall.annotation.rsa.DecodeRsaCommonAnnotation)")
public void pointCut() {
}
/**
* 采用 Rsa 加密算法进行解密
*
* @param joinPoint 切点
*/
@Before("pointCut()")
public void decodeRsaBeforeAdvice(JoinPoint joinPoint) {
try {
// 获取切点方法的参数
Object[] args = joinPoint.getArgs();
// 中间处理 ...
// 对切点方法的参数进行重新赋值
for (int i = 0; i
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!






