gpt4 book ai didi

java - Spring AOP 参数

转载 作者:行者123 更新时间:2023-11-29 04:22:14 26 4
gpt4 key购买 nike


我对 Spring AOP 有疑问。我想在切入点中获取 Student 的对象。但是我的 JoinPoints 可以以任何优先级拥有这个对象。
查看下面的代码片段,了解我创建的两个不同的连接点和切入点:

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。所以问题是如何创建一个切入点,该切入点将针对输入参数中 Student 的任何情况执行。
我无法使用下面的代码,它抛出 runtimeException:
@Before("args(..,com.hadi.student.Student,..)")

我使代码易于理解,实际上我的 Poincut 比这大得多。所以请用args方式回答。

最佳答案

我已经多次回答过类似的问题,例如这里:

您的情况稍微简单一些,因为您只想提取一个参数而不是它的注释。因此,按照其他两个答案,您将使用这样的切入点:

@Before("execution(* *(.., com.hadi.student.Student, ..))")

然后通过遍历 thisJoinPoint.getArgs() 并检查正确的参数类型来提取建议中的参数。这比通过 args() 直接将方法参数绑定(bind)到通知参数更慢也更丑陋,但是你唯一的选择是在任意位置的参数,因为 args(.., Student, ..) 将产生“不明确的参数绑定(bind)”错误。这是因为如果方法中有多个 Student 参数,AspectJ 和 Spring AOP 都无法决定应该发生什么。他们应该选择哪一个?

这是一个 MCVE在 AspectJ 中(不需要 Spring,但在那里的工作方式相同):

Helper 类和驱动程序应用程序:

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]

关于java - Spring AOP 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48391704/

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