Java里使用AspectJ实现AOP

2024-03-04 0 2,765

已经正式从NET转型JAVA。今后开始多写一点JAVA相关的文章

因为已经正式转Java了,所以,对于Java的一些判断,应该就比以前更准确了。总得来说,java有好的东西,有不好的东西,就语言本身和java的常用组件来讲,并不能判断,java比其他语言高一个档次,当然,也不会低一个档次。应该跟其他语言是一个段位的。

但java的调试,确实是比较花费时间,他做不到编译成功后,就能运行成功。这里有注解的问题,有maven的问题,有组件版本的问题。总之,检测的非常不好,非常浪费时间。

java的好处就是,团队成员比较多,毕竟开发起来真的很废人。但好处也在这里,人多,代表着,1,大家的压力都不大,人多压力就会分散。2,功能和性能有时间做的更优秀,人多就是工时多。

而且Java工资确实相对比其他语言高。

总体来说,java是比较幸福的。

开始正文

Aspectj提供一种在字符串里编程的模式,即在字符串里写函数,然后程序启动的时候会动态的把字符串里的函数给执行了。

例如:

"execution(* *(..))"

这里的execution就是一个函数,我们调用它,然后传递的参数是【* *(..)】。

Aspectj 使用
 
使用前,我们先了解一下execution和它的参数的匹配规则:

execution: 用于匹配方法执行的连接点;
execution(public * *(..)) ==> 匹配所有目标类的public方法,第一个*代表返回类型,第二个*代表方法名,而..代表任意入参的方法。
execution(* com.oysept.springboot.controller..*.*(..)) ==> 该包及所有子包下任何类的任何方法。
execution(* com.oysept.springboot.controller.*(..)) ==> 该包下任何类的任何方法。
execution(* com.oysept.springboot.controller.AspectJController.*(..)) ==> 该包下AspectJController类的任何方法。
execution(* com..*.*Controller.method*(..)) ==> 匹配包名前缀为com的任何包下类名后缀为Controller的方法,方法名必须以method为前缀。
execution(* *To(..)) ==> 匹配目标类所有以To为后缀的方法。
注: 该方法只是为了声明一个公共的环绕通知,也可以直接在具体方法配置,如: @Around("execution(* com.oysept.springboot.controller..*.*(..))")

@Before和@AfterReturning

然后我们编写一个aspect的基础使用代码,如下:

/**
 * @Before:定义了前置通知方法。打印出入参
 * @AfterReturning:定义了后置返回通知方法。打印出入参、返参
 */
@Slf4j
@Aspect
@Component
public class AopAspect_Basic {  
    @Before("execution(public * com.k.tender.controller.business.user.UserController.*(..))")
    public void doBefore(JoinPoint point){
        String methodName = point.getSignature().getName();
        List<Object> args = Arrays.asList(point.getArgs());
        log.info("调用前连接点方法为:" + methodName + ",参数为:" + args);
    }

    @AfterReturning(value = "execution(public * com.k.tender.controller.business.user.UserController.*(..))", returning = "returnValue")
    public void doAfterReturning(JoinPoint point, Object returnValue){
        String methodName = point.getSignature().getName();
        List<Object> args = Arrays.asList(point.getArgs());
        log.info("调用前连接点方法为:" + methodName + ",参数为:" + args + ",返回值为:" + returnValue);
    }

}

 如上代码,我们使用了@Before和@AfterReturning注解,在UserController调用前和后,分别埋了点,并输出了函数的入参和出参。

@Pointcut

@Pointcut其实是一个提取execution函数的操作,就是指定一个埋点,然后使用了@Before和@AfterReturning注解时,就不用每次都写那个execution函数了,这样就不用担心写错了。
代码示例如下:

  @Pointcut("execution(public * com.k.tender.controller.business.tender.TenderController.*(..))")
    public void doPointCut() {

    }

    @Before("doPointCut()")
    public void doBefore(JoinPoint point){
        String methodName = point.getSignature().getName();
        List<Object> args = Arrays.asList(point.getArgs());
        log.info("调用前连接点方法为:" + methodName + ",参数为:" + args);
    }

    @AfterReturning(value = "doPointCut()", returning = "returnValue")
    public void doAfterReturning(JoinPoint point, Object returnValue){
        String methodName = point.getSignature().getName();
        List<Object> args = Arrays.asList(point.getArgs());
        log.info("调用前连接点方法为:" + methodName + ",参数为:" + args + ",返回值为:" + returnValue);
    }

对注解埋点

有时候,我们希望编写一个注解,然后让有该注解的函数,都被拦截,那么就可以使用Aspectj的注解埋点模式。

代码如下: 

@Slf4j
@Aspect
@Component
public class AopAspect_Annotation {

    @Before("@annotation(com.k.tender.aop.MyAop)")
    public void doBefore(JoinPoint point){
        String methodName = point.getSignature().getName();
        List<Object> args = Arrays.asList(point.getArgs());
        log.info("调用前连接点方法为:" + methodName + ",参数为:" + args);
    }
    @AfterReturning(value ="@annotation(com.k.tender.aop.MyAop)", returning = "returnValue")
    public void doAfterReturning(JoinPoint point, Object returnValue){
        String methodName = point.getSignature().getName();
        List<Object> args = Arrays.asList(point.getArgs());
        log.info("调用前连接点方法为:" + methodName + ",参数为:" + args + ",返回值为:" + returnValue);
    }
}

public @interface MyAop {
  String value() default "自定义注解拦截";
}

如果觉得写注解的命名空间麻烦,也可以这样写:

@Before("@annotation(apiOperation)")
    public void doBefore(JoinPoint point, MyAopAsyncTask apiOperation) {
        String methodName = point.getSignature().getName();
        List<Object> args = Arrays.asList(point.getArgs());
        log.info("调用前连接点方法为:" + methodName + ",参数为:" + args);
    }

还可以将注解和前面的excution函数结合写:

  @Before("execution(public * com.k..*.*(..)) && @annotation(apiOperation)") 
    public void doBefore(JoinPoint point, MyAopAsyncTask apiOperation) throws NoSuchMethodException {
        String methodName = point.getSignature().getName();
        List<Object> args = Arrays.asList(point.getArgs());
        log.info("调用前连接点方法为:" + methodName + ",参数为:" + args); 
    }

有时候我们的拦截会触发多次,这个具体原因调查起来很麻烦,我们也可以这样解决,代码如下:

 private volatile long hashcode = 0;//应对重复触发
    @Before("execution(public * com.k..*.*(..)) && @annotation(apiOperation)")

    public void doBefore(JoinPoint point, MyAopAsyncTask apiOperation) throws NoSuchMethodException {
        if (hashcode != point.getTarget().hashCode()) {
            log.info("========doBefore========");
            ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = requestAttributes.getRequest();
            String method = request.getMethod();
           
        }

    }

使用hashcode来过滤多次拦截。

 ----------------------------------------------------------------------------------------------------

 到此,Android里使用AspectJ实现AOP就介绍完了。

----------------------------------------------------------------------------------------------------

注:此文章为原创,任何形式的转载都请联系作者获得授权并注明出处!
若您觉得这篇文章还不错,请点击下方的推荐】,非常感谢!

https://www.cnblogs.com/kiba/p/18027435

资源下载此资源下载价格为1小猪币,终身VIP免费,请先
由于本站资源来源于互联网,以研究交流为目的,所有仅供大家参考、学习,不存在任何商业目的与商业用途,如资源存在BUG以及其他任何问题,请自行解决,本站不提供技术服务! 由于资源为虚拟可复制性,下载后不予退积分和退款,谢谢您的支持!如遇到失效或错误的下载链接请联系客服QQ:442469558

:本文采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可, 转载请附上原文出处链接。
1、本站提供的源码不保证资源的完整性以及安全性,不附带任何技术服务!
2、本站提供的模板、软件工具等其他资源,均不包含技术服务,请大家谅解!
3、本站提供的资源仅供下载者参考学习,请勿用于任何商业用途,请24小时内删除!
4、如需商用,请购买正版,由于未及时购买正版发生的侵权行为,与本站无关。
5、本站部分资源存放于百度网盘或其他网盘中,请提前注册好百度网盘账号,下载安装百度网盘客户端或其他网盘客户端进行下载;
6、本站部分资源文件是经压缩后的,请下载后安装解压软件,推荐使用WinRAR和7-Zip解压软件。
7、如果本站提供的资源侵犯到了您的权益,请邮件联系: 442469558@qq.com 进行处理!

猪小侠源码-最新源码下载平台 Java教程 Java里使用AspectJ实现AOP http://www.20zxx.cn/809065/xuexijiaocheng/javajc.html

猪小侠源码,优质资源分享网

常见问题
  • 本站所有资源版权均属于原作者所有,均只能用于参考学习,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担
查看详情
  • 最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,建议提前注册好百度网盘账号,使用百度网盘客户端下载
查看详情

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务