gpt4 book ai didi

java - 子类中自定义注解的Spring AOP切入点表达式

转载 作者:行者123 更新时间:2023-12-04 18:03:32 24 4
gpt4 key购买 nike

我正在处理一个日志记录方面,它需要拦截所有用自定义注释注释的类和方法。

下面是自定义注解类,可以注解在类和方法上:

@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Loggable {
LogLevel value();
}

我正在使用这些切入点表达式来拦截带有注释 @Loggable 的方法和类,它适用于所有简单类,但不适用于扩展或实现的类。

//Works for annotation @Loggable on class level
@Pointcut("execution(* *(..)) && within(@com.logger.Loggable *)")
public void classAnnotationLogger() {
}

//Working for methods annotated with @Loggable
@Before(value = "@annotation(loggable)", argNames = "jp, loggable")
public void logBeforeAdvice(JoinPoint jp, Loggable loggable) {
..
..
}

下面是父类(super class)的代码

@Component
@Loggable(LogLevel.INFO)
public abstract class Processor{
public void process(){
readProcess();
}

public abstract void readProcess();
}

下面是子类的代码

@Service
@Loggable(LogLevel.INFO)
public class MyServiceProcessor extends Processor {

@Override
public void readProcess(){
...
...
}
}

在申请readProcess()通过做调用

Processor processor = applicationContext.getBean(MyServiceProcessor.class);
processor.readProcess();

即使我有@LoggableProcessorMyServiceProcessor , 当 readProcess被称为建议未被调用。

但是为 process() 调用了建议而不是 readProcess .

当注释 @Logabble 时,如何编写切入点表达式,它也拦截对任何子类方法的调用应用于任何类或方法?

最佳答案

嗯,首先是这个

@Pointcut("execution(* *(..)) &&  within(@com.logger.Loggable *)")
public void classAnnotationLogger() {}

只是一个切入点而不是一个建议,所以它不会做任何事情,除非你也有一个实际使用这个切入点的建议。你没有发布这样的建议,所以我只能推测。

其次,您没有提供任何将被触发的示例代码

@Before(value = "@annotation(loggable)", argNames = "jp, loggable")
public void logBeforeAdvice(JoinPoint jp, Loggable loggable) {}

完全没有,即没有注释方法。您的示例代码仅显示带注释的类。

至于子类上的@Loggable注解,应该没有必要,因为它的基类已经带有相同的注解,而且注解是@Inherited。这适用于类上的注释,但不适用于方法或接口(interface)上的注释,请参阅 my other answer以获得解释和可能的解决方法。

你的这个例子应该确实有效,我看不出有什么不可行的原因:

Processor processor = applicationContext.getBean(MyServiceProcessor.class);
processor.readProcess();

但是这个对 readProcess() 的内部调用(等同于 this.readProcess())将不起作用:

public void process() {
readProcess();
}

这是因为 Spring AOP 是一个基于代理的“AOP lite”框架,它依赖于 JDK 动态代理(用于接口(interface))或 CGLIB 代理(用于类)。但是对 this.someMethod() 的调用不会通过任何类型的代理进行路由,因此它们不会被 Spring 方面拦截。这是记录在案的行为。如果您想克服此限制并将方面也应用于内部方法调用,请使用完整的 AspectJ,如文档所述 here .

关于java - 子类中自定义注解的Spring AOP切入点表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31047601/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com