更新时间:2023-08-24 12:11:16
您的代码有几个错误:
public int sleep(String sleepHours)
上.@Retention(RetentionPolicy.RUNTIME)
这样的元注释.@args
是错误的切入点类型.它捕获方法自变量的类型.您想改用@annotation(com.aspect.Sleepable)
.public int sleep(String sleepHours)
.@Retention(RetentionPolicy.RUNTIME)
.@args
is the wrong pointcut type. It captures method arguments the types of which are annotated. You want to use @annotation(com.aspect.Sleepable)
instead.我认为您不应该尝试复制&从Spring AOP开始粘贴冷启动,但请阅读 Spring AOP手册.我在这里解释的所有内容都可以在此处找到.
I think you should not try a copy & paste cold start with Spring AOP but read the Spring AOP manual first. Everything I explained here can be found there.
更新:因此,根据您的评论,您只是在练习并尝试构成@args()
的示例.这是一个简单的AspectJ.您可以在Spring AOP中以类似的形式轻松使用它. @Before
建议显示了如何在带有其类注释的参数上进行匹配,@After
建议还显示了如何将相应的注释绑定到建议参数上.
Update: So according to you comments you were just practicing and trying to make up an example for @args()
. Here is one in plain AspectJ. You can easily use it in similar form in Spring AOP. The @Before
advice shows you how to match on an argument with an annotation on its class, the @After
advice also shows how to bind the corresponding annotation to an advice argument.
使用它的注释+类:
package com.company.app;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {}
package com.company.app;
@MyAnnotation
public class MyClass {}
驱动程序应用程序:
package com.company.app;
public class Application {
public static void main(String[] args) {
new Application().doSomething(new MyClass(), 11);
}
public String doSomething(MyClass myClass, int i) {
return "blah";
}
}
如您所见,这里我们在方法参数中使用带注释的类MyClass
.在以下方面,可以将其与@args()
匹配.
As you can see, here we use the annotated class MyClass
in a method argument. This can be matched with @args()
in the following aspect.
方面:
package com.company.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import com.company.app.MyAnnotation;
@Aspect
public class MyAspect {
@Before("@args(com.company.app.MyAnnotation, ..)")
public void myBeforeAdvice(JoinPoint thisJoinPoint) {
System.out.println("Before " + thisJoinPoint);
}
@After("@args(myAnnotation, ..)")
public void myAfterAdvice(JoinPoint thisJoinPoint, MyAnnotation myAnnotation) {
System.out.println("After " + thisJoinPoint + " -> " + myAnnotation);
}
}
控制台日志:
Before call(String com.company.app.Application.doSomething(MyClass, int))
Before execution(String com.company.app.Application.doSomething(MyClass, int))
After execution(String com.company.app.Application.doSomething(MyClass, int)) -> @com.company.app.MyAnnotation()
After call(String com.company.app.Application.doSomething(MyClass, int)) -> @com.company.app.MyAnnotation()
当然,call()
连接点在Spring AOP中不可用,因此在那里您只会看到两行日志输出.
Of course, call()
joinpoints are unavailable in Spring AOP, so there you would only see two lines of log output.