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

在Spring AOP或AspectJ中拦截带注释的类和方法

燕青青
2023-03-14

所以我有一个自定义注释

java prettyprint-override">@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Intercepted {}

我想使用它将方面编织到方法中(AspectJ,<代码>@注释(截取) )。

其思想是,当我直接注释方法截取时,我将方面编织入其中——这一部分起作用——或者如果我注释类,则应将方面编织入其所有(公共)方法中——这一部分不起作用。

此外,如果我对一个类及其一个方法进行注释,则方面应该只被编织一次,方法级注释将覆盖类级注释。

本质上,我想要一个“如果有类级注释,但只有在还没有方法级注释的情况下,才添加类级注释。”

我该怎么做呢?

共有1个答案

松琦
2023-03-14

这是一个AsheJ示例。切入点语法与Spring AOP中相同。

助手类:

package de.scrum_master.app;

import java.lang.annotation.*;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Intercepted {}
package de.scrum_master.app;

@Intercepted
public class AnnotatedClass {
  public void doSomething() {}
  public void doSomethingElse() {}
}
package de.scrum_master.app;

public class AnnotatedMethod {
  @Intercepted
  public void doSomething() {}
  public void doSomethingElse() {}
}
package de.scrum_master.app;

@Intercepted
public class AnnotatedMixed {
  @Intercepted
  public void doSomething() {}
  public void doSomethingElse() {}
}

驱动程序应用程序(Java SE,无Spring):

package de.scrum_master.app;

public class Application {
  public static void main(String[] args) {
    // Should be logged
    new AnnotatedClass().doSomething();
    // Should be logged
    new AnnotatedClass().doSomethingElse();

    // Should be logged
    new AnnotatedMethod().doSomething();
    // Should NOT be logged
    new AnnotatedMethod().doSomethingElse();

    // Should be logged, but only once
    new AnnotatedMixed().doSomething();
    // Should be logged
    new AnnotatedMixed().doSomethingElse();
  }
}

方面:

请注意执行(**(..)

package de.scrum_master.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class AnnotationInterceptor {
  @Pointcut("@annotation(de.scrum_master.app.Intercepted)")
  public void annotatedMethod() {}

  @Pointcut("@within(de.scrum_master.app.Intercepted)")
  public void annotatedClass() {}

  @Before("execution(* *(..)) && (annotatedMethod() || annotatedClass())")
  public void log(JoinPoint thisJoinPoint) {
    System.out.println(thisJoinPoint);
  }
}

控制台日志

execution(void de.scrum_master.app.AnnotatedClass.doSomething())
execution(void de.scrum_master.app.AnnotatedClass.doSomethingElse())
execution(void de.scrum_master.app.AnnotatedMethod.doSomething())
execution(void de.scrum_master.app.AnnotatedMixed.doSomething())
execution(void de.scrum_master.app.AnnotatedMixed.doSomethingElse())
 类似资料:
  • 我试图让aspectj拦截带注释的方法: 我删除了!为了简洁起见,在(InterceptMeAspect)内,但它并没有拦截太多。如果我删除注释约束(在(@InterceptMe*)内),它可以工作,但会拦截所有内容,这会造成一个大问题。 输出字节码似乎有完整的注释,所以我希望注释标准匹配。我正在或试图进行编译时编织。这很重要,因为我有另一个方面确实使用上面相同的方法工作。我怀疑该方面正在搞乱这个

  • 我想拦截所有用特定注释注释类的构造函数调用。 我有这样一个方面: 还有一个例子: 现在,如果我更改方面并删除@注释过滤器,那么我看到aspectj正在拦截调用。此外,如果我创建一个默认构造函数,然后用注释对其进行注释,它也可以工作。 但是,我希望注释存在于类中,这样如果我有1个构造函数或10个,它们都将被相同地拦截(我只需要将其放在类中)。

  • 我最近用aspectJ和spring-aop添加了AOP到我现有的spring项目中。目标是实际截获控制器调用以修改它们发回的响应,以便将一些值绑定到此响应,我不想手动添加到每个控制器中,例如最终用户使用的实际令牌的到期日期(无论如何我都无法在控制器中显示它)。实际上,在开始单元测试之前,我一直设法让它工作: 在我的单元测试中,我使用java中的反射特性直接调用我的控制器方法,然后复制通常的过程(

  • 我试图截取带注释方法的执行,以记录执行时间;因此,我创建了一个新注释: 我将注释应用于我想要跟踪的方法(该方法的类没有注释,如@Service或@Component;这是一个问题吗?) 然后我创建类和@周围方法: 我在pom中添加了spring boot starter aop依赖项,并在主类中添加了@EnableSpectProxy(带@SpringBootApplication注释的类)。我希

  • add:如果我将方法存根添加到Fragment2中,就可以开始使用next annotation,但这是一个非常难看的解决方案 解决方案:多亏了@Kriegaex,我找到了解决方案:

  • 问题内容: 我需要 在类中使用@X注释的方法或使用@X注释的方法的切入点 。我还 需要注释对象 。如果同时注释了类和方法,则 我更喜欢将方法注释作为参数 。 我尝试了以下操作,这将创建“不一致的绑定”警告。(为什么不将它们设置为null?) 下面创建“跨’||’的参数x的模糊绑定 在切入点”警告。(我认为这并不一定有意义:为什么不绑定第一个短路评估?) 如果存在类和方法注释,则将先前的尝试自然地分