如何解决为Spring AOP注释创建Pointcut,以将注释放在类上,并对类中的每个方法执行建议
我想在类级别具有注释 ,以便在带注释的类中的每个方法上执行建议。 甚至有可能。
示例:我想用OmniDemoService
注释@DoSomethingForMe
,并且我希望 method1 和method2
都记录“ em>在执行之前先看看我”
此示例不起作用,我也不知道为什么。当我将pointcut转换为Around并将其与注释一起使用(还将注释ElementType更改为方法)时,一切都在方法级别上进行。 所以我认为定义切入点是错误的。
注释:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface DoSomethingForMe {
}
建议:
@Aspect
@Component
public class DoSomethingForMeAdvice {
private static final Logger logger = LoggerFactory.getLogger(DoSomethingForMeAdvice.class);
@pointcut("execution(public * *(..)) && @annotation(DoSomethingForMe)")
public void anyAnnotatedMethod() {
}
@Before("anyAnnotatedMethod()")
public void acquireExecution() {
logger.info("look at me");
}
}
用法:
@Service
@DoSomethingForMe
public class OmniDemoService {
private static final Logger logger = LoggerFactory.getLogger(OmniDemoService.class);
public void method1() {
logger.info("---1---");
}
public void method2() {
logger.info("---2---");
}
}
解决方法
您的问题是您将切入点定义与建议混淆了。
切入点是瞄准目标,建议执行实际的WhatYouWantToBeExecuted。例如
@Pointcut("@annotation(com.omnidemo.advice.DoSomethingForMe)")
public void anyAnnotatedMethod() {
}
@Before("anyAnnotatedMethod()")
public void logMethodCall(JoinPoint jp) {
String methodName = jp.getSignature().toShortString();
logger.info("Executing: " + methodName);
}
,
查看AspectJ quick reference对@annotation()
的评价:
主题具有类型注释的任何连接点
SomeAnnotation
您使用了@annotation(DoSomethingForMe)
,但是方法执行的“ subject”是方法。因此,这意味着 any 注释为@DoSomethingForMe的方法。
使用@this(DoSomethingForMe)
或@target(DoSomethingForMe)
。
感谢kriegaex指出必须在运行时对@this
和@target
进行评估,这会污染代码库很多(即,检查每个方法)。因此,下一种方法更好:
如果您查看关于type patterns的AspectJ手册部分,将会看到可以直接注释类型。还请记住使用完全限定的类名。这样就可以了:
execution(public * (@com.path.DoSomethingForMe *).*(..))
此外,如果您有一个简单的切入点并且不需要重用它,我想您可以删除其他方法,并直接在建议中使用它:
@Before("execution(public * (@com.path.DoSomethingForMe *).*(..))")
表示:“在执行任何带有@com.path.DoSomethingForMe
注释的类型的公共方法之前”,其中“在执行方法之前”是指“在方法内部,开始时”。
或者,如果这个切入点对您来说太复杂了,您可以像J Asgarov在他的评论中建议的那样,将注释匹配和方法匹配分开:
@Before("execution(public * *(..)) && @within(com.path.DoSomethingForMe)")
,
该问题的解决方案是在切入点中使用
@Pointcut("@within(DoSomethingForMe)")
public void anyAnnotatedMethod() {
}
@Before("anyAnnotatedMethod()")
public void acquireExecution() {
logger.info("look at me");
}
@J Asgarov在评论中提供的解决方案
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。