Java 如何正确使用SpringAOP选择使用特定注释注释的方法的执行?

Java 如何正确使用SpringAOP选择使用特定注释注释的方法的执行?,java,spring,spring-mvc,aop,spring-aop,Java,Spring,Spring Mvc,Aop,Spring Aop,我正在研究SpringAOP,我对在我的研究材料中发现的一个问题有以下疑问 考虑下面的切入点:执行(@ COM.MyApp.MyCueValueNoTyVal*(..))< /强>。到底是什么意思 它给了我以下的答案,在我看来有点奇怪(使用我对AOP工作原理的知识)。它说: 这将选择表示voiud方法的关节点 由@com.myapp.MyCustomAnnotation注释 好的,那么使用AOP我可以指定何时执行带有特定注释的特定方法意味着什么呢?这是对的还是我遗漏了什么 因此,如果前面的断言是

我正在研究SpringAOP,我对在我的研究材料中发现的一个问题有以下疑问

考虑下面的切入点:<强>执行(@ COM.MyApp.MyCueValueNoTyVal*(..))< /强>。到底是什么意思

它给了我以下的答案,在我看来有点奇怪(使用我对AOP工作原理的知识)。它说:

这将选择表示voiud方法的关节点 由@com.myapp.MyCustomAnnotation注释

好的,那么使用AOP我可以指定何时执行带有特定注释的特定方法意味着什么呢?这是对的还是我遗漏了什么

因此,如果前面的断言是正确的,这意味着(例如)我还可以指定类似这样的内容:“当执行由@RequestMapping(“/listcounts”)注释的控制器方法时”(这意味着,当控制器对/listcounts资源处理HttpRequest时,执行如下操作:

execution(@RequestMapping("/listAccounts") * *(..))

我是否可以这样做?

Spring正在使用AspectJ切入点表达式语言()

应用切入点表达式意味着拦截所有具有“void”返回类型的任何名称和参数列表的方法调用,只要该方法使用@com.myapp.MyCustomAnnotation注释


但是,无法使用注释参数匹配连接点,因此您的第二个切入点表达式无效。

您不能像那样在切入点中显式指定注释的参数。相反,您可以设置切入点以捕获带有
@RequestMapping
注释的所有方法,然后检索注释n并检查该值是否与端点匹配。例如:

@PointCut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
public void requestMapping() {}

@Before("requestMapping()")
public void handleRequestMapping(JoinPoint joinPoint) {
    MethodSignature signature = (MethodSignature) joinPoint.getSignature();
    Method method = signature.getMethod();
    String mapping = method.getAnnotation(RequestMapping.class).value()[0];

    if (mapping.equals("/listAccounts") {
        // do something
    }
}

AndréR.的答案是不正确的,因为可以将注释匹配限制为参数值,但有一个限制:它只适用于字符串、整数和类等简单类型,而不适用于字符串数组等。但是在您的特定示例中,Spring注释
@RequestMapping
的值类型是 字符串[],请参阅。假设您有以下情况:

注释:

package de.scrum\u master.app;
导入java.lang.annotation.ElementType;
导入java.lang.annotation.Retention;
导入java.lang.annotation.RetentionPolicy;
导入java.lang.annotation.Target;
@目标(值={ElementType.METHOD,ElementType.TYPE})
@保留(RetentionPolicy.RUNTIME)
public@interface-MyAnnotation{
int值();
字符串名()默认为“”;
Class type()默认对象.Class;
}
驱动程序应用程序:

这里我们有一个应用程序,它有几个方法,由Spring注释
@RequestMapping
和我们自制的注释
@MyAnnotation
注释:

package de.scrum\u master.app;
导入org.springframework.web.bind.annotation.RequestMapping;
导入org.springframework.web.bind.annotation.RequestMethod;
公共类应用程序{
@请求映射(“/listAccounts”)
@MyAnnotation(11)
公共void doSomething(){}
公共无效doSomethingElse(){}
@RequestMapping(值={“/listAccounts”,“/Other/method”},name=“Newton”)
@MyAnnotation(值=22,类型=String.class)
公共void foo(){}
@RequestMapping(value=“/listAccounts”,method=RequestMethod.POST,name=“Einstein”)
@MyAnnotation(value=11,name=“John Doe”,type=String.class)
公共无效条(){}
@RequestMapping(value=“/listCustomers”,method=RequestMethod.GET,name=“Einstein”)
@MyAnnotation(value=22,name=“Jane Doe”)
公共void zot(){}
@RequestMapping(value=“/listAccounts”,products={“application/json”,“application/xml”},consumes=“text/html”,name=“Newton”)
公共void baz(){}
公共静态void main(字符串[]args){
应用程序=新应用程序();
application.doSomething();
application.doSomethingElse();
application.foo();
application.bar();
application.zot();
application.baz();
}
}
注释匹配方面:

package de.scrum\u master.aspect;
导入java.util.array;
导入org.aspectj.lang.JoinPoint;
导入org.aspectj.lang.annotation.Aspect;
导入org.aspectj.lang.annotation.Before;
导入org.springframework.web.bind.annotation.RequestMapping;
导入de.scrum_master.app.MyAnnotation;
@面貌
公共类AnnotationParameterMatcher{
//匹配@RequestMapping注释的*all*方法
@在(“执行(**(..)&&&@注释(请求映射)”之前
public void logRequestMapping(JoinPoint thisJoinPoint,RequestMapping RequestMapping){
//打印连接点和注释
System.out.println(thisJoinPoint+“->”+请求映射);
}
//匹配@RequestMapping注释的*all*方法
@在(“执行(**(..)&&&@注释(请求映射)”之前
公共void日志匹配值(JoinPoint thisJoinPoint,RequestMapping RequestMapping){
//仅当值数组包含“/listAccounts”时才打印
if(Arrays.asList(requestMapping.value())包含(“/listAccounts”))
System.out.println(“值包含“/listcounts”);
}
//匹配@RequestMapping注释的*all*方法并绑定'name'参数
@在(“执行(**(..)&&&&@注释(请求映射(名称))之前)
public void日志名(JoinPoint thisJoinPoint,字符串名){
System.out.println(“name=”+name+“”);
}
//匹配@MyAnnotation注释的方法,值为11
@之前(“执行(@MyAnnotation(value=11)**(..)”)
公共无效日志名(JoinPoint thisJoinPoint){
System.out.println(“@MyAnnotation(value=11)检测到”);
}
//匹配法