我正在学习Spring,我搜索了很多关于如何正确使用@args()AspectJ指示符但我仍然不完全清楚。我所知道的是它限制了联合点匹配,以执行其参数使用给定注释类型注释的方法。这在我的案例中似乎不起作用。
所以这里是我的文件:
Human.java
@Component
public class Human {
int sleepHours;
public int sleep(String sleepHours) {
this.sleepHours = Integer.parseInt(sleepHours);
System.out.println("Humans sleep for " + this.sleepHours + " hours.");
return this.sleepHours+1;
}
}
Sleepable.java - 可注册的注释
package com.aspect;
public @interface Sleepable {
}
SleepingAspect.java - 方面
@Component
@Aspect
public class SleepingAspect {
@Pointcut("@args(com.aspect.Sleepable)")
public void sleep(){};
@Before("sleep()")
public void beforeSleep() {
System.out.println("Closing eyes before sleeping");
}
@AfterReturning("sleep()")
public void afterSleep() {
System.out.println("Opening eyes after sleep");
}
}
MainApp.java
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Human human = (Human) context.getBean("human");
@Sleepable
String sleepHours = "8";
human.sleep(sleepHours);
}
}
输出
人类睡了8个小时。
预期输出
睡觉前闭上眼睛
人类睡了8个小时。
睡觉后睁开眼睛
答案 0 :(得分:1)
您的代码中有几个错误:
public int sleep(String sleepHours)
。@Retention(RetentionPolicy.RUNTIME)
之类的元注释。@args
是错误的切入点类型。它捕获方法参数,其类型被注释。您想改用@annotation(com.aspect.Sleepable)
。我认为你不应该试试副本&使用Spring AOP粘贴冷启动,但首先阅读Spring AOP manual。我在这里解释的一切都可以在那里找到。
更新:根据您的评论,您只是在练习并尝试为@args()
编写示例。这是一个简单的AspectJ。您可以在Spring AOP中以类似的形式轻松使用它。 @Before
建议向您展示如何在其类上使用注释匹配参数,@After
建议还显示如何将相应的注释绑定到建议参数。
使用它的注释+类:
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()
匹配。
<强>方面:强>
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()
当然,Spring {AOP中的call()
个连接点不可用,所以你只能看到两行日志输出。