17

如果出现以下情况,我需要创建一个切入点与方法匹配的方面:

  • 是否公开
  • 它的类用@Controller注解 (最后没有)
  • 它的一个参数(可以有很多)使用@MyParamAnnotation 进行注释。

我认为前两个条件很容易,但我不知道是否可以使用 Spring 完成第三个条件。如果不是,也许我可以将其更改为:

  • 它的参数之一是 com.me.MyType 类型的实例(或实现某些接口)

您认为有可能实现这一目标吗?性能会好吗?

谢谢

编辑:匹配方法的一个例子。如您所见,MyMethod 没有注释(但可以)。

@Controller
public class MyClass {
    public void MyMethod (String arg0, @MyParamAnnotation Object arg1, Long arg3) {
        ...
    }
}

编辑:我最终使用的解决方案,基于@Espen 的答案。正如你所看到的,我稍微改变了我的条件:类实际上不需要是@Controller。

@Around("execution(public * * (.., @SessionInject (*), ..))")
public void methodAround(JoinPoint joinPoint) throws Exception {
    ...
}
4

1 回答 1

22

这是一个有趣的问题,所以我创建了一个小示例应用程序来解决这个问题!(并在事后根据Sinuhe的反馈对其进行了改进。)

我创建了一个DemoController应该作为方面示例的类:

@Controller
public class DemoController {

    public void soSomething(String s, @MyParamAnnotation Double d, Integer i) {
    }

    public void doSomething(String s, long l, @MyParamAnnotation int i) {
    }

    public void doSomething(@MyParamAnnotation String s) {
    }

    public void doSomething(long l) {
    }
}

将在前三个方法上添加连接点的方面,但不是参数未注释的最后一个方法@MyParamAnnotation

@Aspect
public class ParameterAspect {

    @Pointcut("within(@org.springframework.stereotype.Controller *)")
    public void beanAnnotatedWithAtController() {
    }

    @Pointcut("execution(public * *(.., @aspects.MyParamAnnotation (*), ..))")
    public void methodWithAnnotationOnAtLeastOneParameter() {
    }

    @Before("beanAnnotatedWithAtController() " 
            + "&& methodWithAnnotationOnAtLeastOneParameter()")
    public void beforeMethod() {    
        System.out.println("At least one of the parameters are " 
                  + "annotated with @MyParamAnnotation");
    }
}

第一个切入点将在标有 的类中的所有方法上创建一个连接点@Controller

当满足以下条件时,第二个切入点将添加一个连接点:

  • 公共方法
  • first*是每个返回类型的通配符。
  • second*是所有类中所有方法的通配符。
  • (..,在带注释的参数之前匹配零到多个任何类型的参数。
  • @aspects.MyParamAnnotation (*),匹配使用给定注释注释的参数。
  • ..)在带注释的参数之后匹配零到多个任何类型的参数。

最后,@Before建议会建议所有方法,其中两个切入点中的所有条件都满足。

切入点适用于 AspectJ 和 Spring AOP!

说到性能。开销很小,尤其是使用在编译时或加载时进行编织的 AspectJ。

于 2010-05-04T16:12:04.243 回答