gpt4 book ai didi

java - Spring AOP 切入点不适用于可变参数

转载 作者:太空宇宙 更新时间:2023-11-04 06:50:31 24 4
gpt4 key购买 nike

当参数之一是可变参数时,我无法使 spring-AOP 切入点正常工作。鉴于下面的代码,我预计切入点会在我的测试的两次调用中触发,但是在这两种情况下都不会调用它。我在同一个类中的其他方法上还有其他方面的工作,所以我知道这不是我的测试或 spring 设置的问题 - 它似乎与此方法隔离,唯一独特的是 vararg。

方法声明:

SearchResults getRelation(final ClmUserContextFactory contextFactory, final CloudObjectId objectId,
final Class<? extends CloudClass>... relationClasses) throws BmcClientException;

切入点声明:

@Around(value = "execution(com.a.b.SearchResults "
+ "com.a.b.BmcClmRestJsonClient.getRelation(com.a.b.ClmUserContextFactory, com.a.b.CloudObjectId, Class<? extends com.a.b.CloudClass>...))"
+ " && args(contextFactory, objectId, relationClasses)",
argNames = "jp,contextFactory,objectId,relationClasses")
private SearchResults getRelationVarargs(ProceedingJoinPoint jp, ClmUserContextFactory contextFactory,
CloudObjectId objectId,
Class<? extends CloudClass>[] relationClasses)
throws Throwable
{...}

来自测试的调用:

bmcClmRestJsonClient.getRelation(contextFactory, objectId, new Class[] { CloudClass.class });

bmcClmRestJsonClient.getRelation(contextFactory, objectId);

编辑:

我可以确认,如果我从切入点和方法定义中删除定义的 vararg 部分(即删除所有“...”和“[]”),它就可以工作,所以它肯定与这些有关。如果我将“...”替换为“[]”,它也不起作用。

最佳答案

我不是 Spring 用户,但我用 AspectJ 尝试过,无论是代码样式还是注释样式语法。对我来说它是有效的,所以我认为如果你的切入点定义正确的话它也应该对你有效。

更新:我还认为您的建议方法必须是公开的,而不是私有(private)的。

示例驱动程序应用程序:

package de.scrum_master.app;

public class Application {
public static void main(String[] args) {
System.out.println("Starting application");
doSomething(11, String.class, String.class);
System.out.println("Stopping application");
}

public static boolean doSomething(final int number, final Class<? extends String>... classes) {
System.out.println("Doing something");
return true;
}
}

代码风格方面:

package de.scrum_master.aspect;

import de.scrum_master.app.Application;

public aspect CodeStyleAspect {
boolean around(int number, Class<? extends String>[] classes) :
execution(boolean Application.doSomething(int, Class<? extends String>...)) &&
args(number, classes)
{
System.out.println(this.getClass().getName());
System.out.println(thisJoinPointStaticPart);
System.out.print("number = " + number + ", classes = { ");
for (Class<? extends String> clazz : classes)
System.out.print(clazz.getName() + ", ");
System.out.println("}");
return proceed(number, classes);
}
}

注释风格方面:

package de.scrum_master.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class AnnotationStyleAspect {
@Around(
"execution(boolean de.scrum_master.app.Application.doSomething(int, Class<? extends String>...)) &&" +
"args(number, classes)"
)
public Object myAdvice(ProceedingJoinPoint thisJoinPoint, int number, Class<? extends String>[] classes) throws Throwable {
System.out.println(this.getClass().getName());
System.out.println(thisJoinPoint.getStaticPart());
System.out.print("number = " + number + ", classes = { ");
for (Class<? extends String> clazz : classes)
System.out.print(clazz.getName() + ", ");
System.out.println("}");
return thisJoinPoint.proceed(new Object[] { number, classes });
}
}

两个方面均处于 Activity 状态的示例输出:

Starting application
de.scrum_master.aspect.CodeStyleAspect
execution(boolean de.scrum_master.app.Application.doSomething(int, Class[]))
number = 11, classes = { java.lang.String, java.lang.String, }
de.scrum_master.aspect.AnnotationStyleAspect
execution(boolean de.scrum_master.app.Application.doSomething(int, Class[]))
number = 11, classes = { java.lang.String, java.lang.String, }
Doing something
Stopping application

正如您所看到的,这两个方面基本上以相同的方式工作并产生相同的结果。

关于java - Spring AOP 切入点不适用于可变参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23357752/

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