我对Spring有个问题。我想把学生的目标放在一个圆点上。但是我的JoinPoints可以有任何优先级的对象。
请看下面为我创建的两个不同的JoinPoints和Pointcut编写的代码片段:
public Student createStudent(String s, Student student) {...}
public Student updateStudent(Student student, String s) {...}
@Before("args(..,com.hadi.student.Student)")
public void myAdvice(JoinPoint jp) {
Student student = null;
for (Object o : jp.getArgs()) {
if (o instanceof Student) {
student = (Student) o;
}
}
}以上代码仅适用于第一个JoinPoint。因此,问题是如何创建一个切入点,将执行的任何情况下的学生在输入参数。
我无法使用下面的代码,它抛出runtimeException:
@Before("args(..,com.hadi.student.Student,..)")
我让代码很容易理解,实际上我的切入点比这个更大。所以请用args的方式回答。
发布于 2018-01-23 01:39:12
我曾多次回答类似的问题,例如:
您的情况比较简单,因为您只想提取一个参数,而不是它的注释。因此,按照另外两个答案的思路,您可以使用这样的切入点:
@Before("execution(* *(.., com.hadi.student.Student, ..))")然后通过迭代thisJoinPoint.getArgs()并检查正确的参数类型,提取建议中的参数。这比通过args()将方法参数直接绑定到通知参数要慢和丑陋,但是您在任意位置的参数的唯一选项是,因为args(.., Student, ..)将产生“模糊参数绑定”错误。这是因为AspectJ和Spring都无法决定如果方法中有多个Student参数应该发生什么。他们应该选择哪一个?
下面是MCVE in AspectJ (不需要Spring,但在那里的工作方式相同):
帮助类和驱动程序应用程序:
package de.scrum_master.app;
public class Student {
private String name;
public Student(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student [name=" + name + "]";
}
}package de.scrum_master.app;
public class Application {
public void doSomething() {}
public Student createStudent(String s, Student student) {
return student;
}
public Student updateStudent(Student student, String s) {
return student;
}
public void marryStudents(Student student1, Student student2) {}
public static void main(String[] args) {
Application application = new Application();
application.doSomething();
application.createStudent("x", new Student("John Doe"));
application.updateStudent(new Student("Jane Doe"), "y");
// What happens if we have multiple Student parameters?
application.marryStudents(new Student("Jane"), new Student("John"));
}
}方面:
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import de.scrum_master.app.Student;
@Aspect
public class MyAspect {
@Before("execution(* *(.., de.scrum_master.app.Student, ..))")
public void interceptMethodsWithStudentArgs(JoinPoint thisJoinPoint) throws Throwable {
System.out.println(thisJoinPoint);
for(Object arg : thisJoinPoint.getArgs()) {
if (!(arg instanceof Student))
continue;
Student student = (Student) arg;
System.out.println(" " + student);
}
}
}控制台日志:
execution(Student de.scrum_master.app.Application.createStudent(String, Student))
Student [name=John Doe]
execution(Student de.scrum_master.app.Application.updateStudent(Student, String))
Student [name=Jane Doe]
execution(void de.scrum_master.app.Application.marryStudents(Student, Student))
Student [name=Jane]
Student [name=John]https://stackoverflow.com/questions/48391704
复制相似问题