当前位置: 首页 > news >正文

Java切面中各个方法对象、参数对象、反射以及注解的分析

说明:
本文以环绕切面配合反射、注解为示例

	@Around(value = "cutMethods() && withAnnotationMethods()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        long startTime = System.currentTimeMillis();

        MethodSignature methodSignature = (MethodSignature) point.getSignature();
        Method method = methodSignature.getMethod();
        BusinessLock lockAnnotation = method.getAnnotation(BusinessLock.class);

        //获取参数的类型和名称
        Parameter[] parameters = method.getParameters();

        //获取所有参数的值
        Object[] args = point.getArgs();

        //获取全部参数信息数组、以及每个参数的全部注解信息数组
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();


        //方法执行之前动作,等效于@Before
        Object res = point.proceed();
        //方法执行之后动作,等效于@After



        log.info("执行方法耗时(毫秒)为:" + (System.currentTimeMillis() - startTime));
        return res;
    }

一、环绕增强切入

1、@Around(value = "xxx() && xxx()")
【1】value值为切入条件,可以切入controller层、service层、指定注解等
【2】public Object around(ProceedingJoinPoint point) 入参为切入点对象,里面包括切入方法的所有信息,包括方法名、参数信息、返回信息等

2、获取方法对象
【1】MethodSignature methodSignature = (MethodSignature) point.getSignature(),通过切入点对象获取方法签名对象
【2】Method method = methodSignature.getMethod(),从方法签名对象中获取方法对象

3、获取参数的类型和名称
【1】Parameter[] parameters = method.getParameters(),获取参数个数、类型、名称

4、获取所有参数的值
【1】Object[] args = point.getArgs(),获取参数的值信息,注意是 值

5、获取全部参数信息数组、以及每个参数的全部注解信息数组
【1】Annotation[][] parameterAnnotations = method.getParameterAnnotations(),返回的是个二维数组,第一维度包含切入方法的全部参数信息、第二维度包含每个参数对应的注解信息
【2】验证示例如下:
验证用 api 代码

	@ApiOperation(value = "公共测试接口")
    @GetMapping("/testPublicApi")
    public CommonResult<String> testPublicApi(@BusinessLockKey Long id, @BusinessLockKey @FieldConvert String code, String name) {
	    System.out.println("主线程运行结束");
        return success("成功!");
    }

验证用 aop 代码

//获取参数的类型和名称
Parameter[] parameters = method.getParameters();
	
//获取全部参数信息数组、以及每个参数的全部注解信息数组
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
for (int i = 0; i < parameterAnnotations.length; i++) {
    System.out.println("第" + (i + 1) + "个参数:" + parameters[i].getName() + " 有" + parameterAnnotations[i].length + "个注解");

    Annotation[] parameterAnnotationss = parameterAnnotations[i];
    for (int j = 0; j < parameterAnnotationss.length; j++) {
        //System.out.println("第" +(i+1)+ "个参数:"+parameters[i].getName()+" 的第" +(j+1)+ "个注解为:" + parameterAnnotationss[j]);
        System.out.println("第" + (i + 1) + "个参数:" + parameters[i].getName() + " 的第" + (j + 1) + "个注解为:" + parameterAnnotationss[j]);
    }
}

输出:

第1个参数:id 有1个注解
第1个参数:id 的第1个注解为:@com.hkl.annotation.BusinessLockKey(name="")
第2个参数:code 有2个注解
第2个参数:code 的第1个注解为:@com.hkl.annotation.BusinessLockKey(name="")
第2个参数:code 的第2个注解为:@com.hkl.annotation.FieldConvert(codeType="", value="")
第3个参数:name 有0个注解
主线程运行结束

二、总结

1、Java Aspect 切面可以定义规则切入任意切入点

2、Java切面可以通过切入点对象 ProceedingJoinPoint 配合反射、注解、方法签名对象、参数对象等灵活获取各种信息,从而对请求执行业务前后进行不同的拦截处理动作

3、Java Aspect 中最重要、也是最常用的 @Around 环绕增强切入,其中切入点对象的方法 point.proceed() 为执行我们的业务方法

相关文章:

  • 图解curator如何实现zookeeper分布式锁
  • web入门-命令执行
  • 复盘-----自适应
  • Docker搭建私有镜像仓库及推送、拉取私服镜像
  • 端口转发工具Rinetd详细入门教程
  • 复盘-----CSS(cascading style sheets)1
  • [附源码]计算机毕业设计项目管理系统的专家评审模块Springboot程序
  • 用R语言和python进行社交网络中的社区检测
  • Android 10.0 Launcher3单层高斯模糊(毛玻璃)效果的实现
  • 自定义RBAC(1)
  • (Qt) 子组件绘制QPainter
  • (附源码)springboot平衡膳食小程序 毕业设计 250859
  • [附源码]计算机毕业设计基于springboot的图书互换系统
  • 二叉树OJ题详解
  • 十一、面向对象 其他要点
  • 数据结构—树、有序二叉树
  • Spring Boot文档阅读笔记-Scheduling Tasks
  • HTML爱心照片墙源码
  • [附源码]计算机毕业设计基于SpringBoot的党务管理系统
  • 使用Python和SAS Viya分析社交网络
  • Java---微服务---分布式搜索引擎elasticsearch(1)
  • 四轮两驱小车(三):STM32驱动MPU6050进行转弯
  • 【Linux】Linux和Window下\r与\n的区别、git命令行的使用
  • python语法 dot函数
  • Java多线程与并发之线程同步[91]
  • C语言基础知识(42)