当前位置: 首页 > 知识库问答 >
问题:

Spring AOP-类和方法的自定义注释

李星波
2023-03-14

现有的答案很好地解释了如何在方法执行时间日志中使用自定义注释。我想知道是否有办法对类和方法使用相同的注释,但是点切应该在使用它的地方有所不同。

@LogExecutionTime
public class MyServiceImpl implements MyService {

    public void run(){
       // logic
    }

    public void walk(){
       // logic
    }

    private void breather(){
       // logic
    }
}

若注释用于类,那个么类中的所有方法都应该考虑在方面类中记录执行时间(比如Execution(*com.me.package.MyServiceImpl.*(..) )。但是,如果注释只用于类内的单个方法,那么也应该考虑Acth-Type类中的唯一方法。(如execution(*com.you.package.YourServiceImpl.forward(..) )。

public class YourServiceImpl implements YourService {

    @LogExecutionTime
    public void forward(){
       // logic
    }

    @LogExecutionTime
    public void backward(){
       // logic
    }

    private void upward(){
       // logic
    }
}

注释类

package com.myproj.core.utils.annotation;

import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;

@Retention(RUNTIME)
public @interface LogExecutionTime {

}

注释的方面类(使用@kriegaex建议的切入点)

package com.myproj.core.utils;

import java.time.Duration;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

import java.time.Instant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Aspect class to Log Method Execution time
 */
@Aspect
public class MyMethodExecutionLoggingAspect {
    
    private static final Logger LOG = LoggerFactory.getLogger(MyMethodExecutionLoggingAspect.class);
    
    /**
     * This method will log Method Execution Time
     * 
     * @param joinPoint
     * @return object
     * @throws Throwable
     */
    @Around("execution(* (@com.myproj.core.utils.annotation.LogExecutionTime *).*(..)) || execution(@com.myproj.core.utils.annotation.LogExecutionTime * *(..))")
    public Object log(ProceedingJoinPoint joinPoint) throws Throwable {

        String className = joinPoint.getTarget().getClass().getSimpleName();
        String methodName = joinPoint.getSignature().getName();
        Instant start = Instant.now();

        try {
            return joinPoint.proceed();
        } finally {

            long end = Duration.between(start, Instant.now()).toMillis();

            if (end > 0) {
                LOG.debug("METHOD EXECUTION TIME LAPSED: {}ms | {}.{}", end, className, methodName);
            }
        }

    }
    
}

Spring中的Springbean定义。xml

<代码>


共有1个答案

赫连方伟
2023-03-14
匿名用户

带有@annotation()的示例代码没有意义,因为您没有指定方法注释类型。它应该类似于@annotation(full.qualified.AnnotationType)

为了匹配类注释,您需要在(fully.qualified.AnnotationType)中使用@,如下所述。

所以你可以用这样的切入点

@annotation(fully.qualified.AnnotationType)
  || @within(fully.qualified.AnnotationType)

或者,根据我在这里的回答,你也可以使用更神秘的版本

execution(* (@fully.qualified.AnnotationType *).*(..))
  || execution(@fully.qualified.AnnotationType * *(..))

 类似资料:
  • 本文向大家介绍创建自定义的Java注解类的方法,包括了创建自定义的Java注解类的方法的使用技巧和注意事项,需要的朋友参考一下  如果你已经在使用Java编程,并且也使用了任何像Spring和Hibernate这样的流行框架,那么你应该对注解的使用非常地熟悉。使用一个现有框架工作的时候,通常使用它的注解就够了。但是,你是不是也有时候有要创建属于你自己的注解的需求呢? 不久之前,我找到了一个自己创建

  • 我试图在切入点中检测用注释注释的类的任何方法。 我试过这个: 但它不起作用。我做错了什么? 谢谢

  • 本文向大家介绍MyBatis Generator 自定义生成注释的方法,包括了MyBatis Generator 自定义生成注释的方法的使用技巧和注意事项,需要的朋友参考一下 最近做项目,ORM 使用的是 MyBatis,为了偷懒,我自然而然的想到了使用 MyBatis Generator(MBG)来生成数据库表对应的实体代码和 Mapper 代码。于是做了如下的配置(对 MBG 配置不熟悉的同学

  • 我正在编写一个库/sdk,它可以拦截任何使用自定义注释进行注释的方法。代码的工作方式有点像这样 截取这个的方面有一个切入点表达式 当我在与相同的包中描述方面时,此代码工作正常。但是,如果我创建一个单独的库并定义方面,因为它无法拦截。有帮助吗? 回应@Bond的评论 Spring版本:Spring上下文-4.1.7。发布aspectj-1.6.5问题的关键是注释不会在同一个项目中使用。在编译之后,它

  • 本章将会讨论如何在API设计中使用自定义方法。 自定义方法指的是五个标准方法之外的API方法。他们应当仅用于标准方法不易表达的功能。一般而言,API设计者应当尽可能优先考虑使用标准方法,而不是自定义方法。标准方法相对更简单,定义完善的语义,并且开发者也更加熟悉;这使标准方法更易用,并且使用者更难犯错。使用标准方法的另一个优势是API平台会有更好的支持,如计费、错误处理、日志、监控等等。 自定义方法

  • 类定义 特殊类定义 模块定义 方法定义 方法定义的嵌套 方法的计算 特殊方法定义 类方法的定义 调用限制 与定义有关的操作 alias undef defined? 类定义 例: class Foo < Super def test : end : end 语法: class 标识符 [`<' superclass ] 表达式.. end 语法:ruby 1.7