Java里使用AspectJ实现AOP

这篇具有很好参考价值的文章主要介绍了Java里使用AspectJ实现AOP。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

 前言

已经正式从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

 Java里使用AspectJ实现AOP

 文章来源地址https://www.toymoban.com/news/detail-836686.html

到了这里,关于Java里使用AspectJ实现AOP的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JAVA:使用 Spring AOP 实现面向切面编程

    1、简述 在现代的软件开发中,面向切面编程(AOP)是一种重要的编程范式,它允许我们将横切关注点(如日志记录、性能监控、事务管理等)从应用程序的核心业务逻辑中分离出来,以提高代码的模块化和可维护性。Spring 框架提供了强大的 AOP 支持,使得我们可以轻松地实

    2024年04月13日
    浏览(33)
  • Java使用Aop实现用户操作日志记录(新手入门)

    导入打印日志,aop,hutool,的依赖,Hutool是一个Java工具包,里面封装了大量的常用工具类,到时候咱们就通过这个工具包中有一个工具类可以用来获取客户端IP地址。 自定义操作类型枚举类 因为基本是增删改查四个方法 自定义用来记录用户操作日志的注解 写一个方法加上我

    2024年02月06日
    浏览(37)
  • 温州首个元宇宙创新中心正式开园,助推温企数字化转型

    10月13日,温州元宇宙创新中心正式开园,这是温州首个以元宇宙和区块链为主题的产业园区。 参与开园仪式的领导有龙湾区委副书记、区长、高新区党工委副书记夏禹桨、温州高新区党工委委员、温州高新区(经开区)管委会副主任黄少燕,以及高新区经济发展局、投资促

    2023年04月09日
    浏览(31)
  • 在Mac上安装Aspectj1.9.8(用于Java17)+IDEA

    1. 确定所使用的Java版本和AspectJ的对应关系 2. 下载AspectJ包 3. 安装AspectJ 4. 添加AspectJ对应的环境变量 5. AspectJ测试-简单终端测试 6. AspectJ测试-通过IDEA敲代码测试 ---------------------------------------详细教程--------------------------------------- 1. 确定所使用的Java版本和AspectJ的对应关系

    2024年02月11日
    浏览(24)
  • Java注解方式实现aop,切点切面实战

    注解方式实现aop我们主要分为如下几个步骤(有更好的方法的话,欢迎交流): 1.在切面类(为切点服务的类)前用@Aspect注释修饰,声明为一个切面类。 2.用@Pointcut注释声明一个切点,目的是为了告诉切面,谁是它的服务对象。(此注释修饰的方法的方法体为空,不需要写功

    2024年02月12日
    浏览(25)
  • 8.4Java EE——基于注解的AOP实现

    元素 描述 @Aspect 配置切面 @Pointcut 配置切点 @Before 配置前置通知 @After 配置后置通知 @Around 配置环绕方式 @AfterReturning 配置返回通知 @AfterThrowing 配置异常通知 下面通过一个案例演示基于注解的AOP的实现,案例具体实现步骤如下。

    2024年02月15日
    浏览(29)
  • 8.3Java EE——基于XML的AOP实现

    使用AOP代理对象的好处         因为Spring AOP中的代理对象由IoC容器自动生成,所以开发者无须过多关注代理对象生成的过程,只需选择连接点、创建切面、定义切点并在XML文件中添加配置信息即可。 Spring提供了一系列配置Spring AOP的XML元素。 配置Spring AOP的XML元素 元素 描

    2024年02月15日
    浏览(32)
  • Java实战:Spring Boot实现AOP记录操作日志

    本文将详细介绍如何在Spring Boot应用程序中使用Aspect Oriented Programming(AOP)来实现记录操作日志的功能。我们将探讨Spring Boot集成AOP的基本概念,以及如何使用Spring Boot实现AOP记录操作日志。最后,我们将通过一个具体示例来演示整个实现过程。本文适合已经具备Spring Boot基础

    2024年02月22日
    浏览(41)
  • Java AOP 通过注解实现切面及通过注解改变返回值

    学习过java的小伙伴都知道Spring的重要知识点之一就是AOP,AOP也就是切面编程,切面编程它能够帮助我们实现非侵入式的功能增强,解耦现有的业务逻辑和要新增的功能增强。 实际应用中的场景 事务管理、拦截器、日志处理、权限控制等。 AOP的增强方式 前置增强、后置增强

    2024年02月14日
    浏览(28)
  • Java | 使用切面AOP拦截并修改Controller接口请求参数

    关注common wx: CodingTechWork   在开发过程中,会有一些需求将controller层的一些方法入参进行全量转换,最容易想到的可能是在调用下层service方法时,调用公共的方法进行入参转换,这时带来的唯一问题就是代码不雅观,比较冗余。那还有什么方法可以更优雅的解决这个问题

    2024年01月24日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包