带注释参数的切入点匹配方法 [英] Pointcut matching methods with annotated parameters

查看:31
本文介绍了带注释参数的切入点匹配方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要创建一个切入点与方法匹配的方面,如果:

I need to create an aspect with a pointcut matching a method if:

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

我认为前两个条件很容易,但我不知道是否可以用Spring来完成第三个条件.如果不是,也许我可以把它改成:

I think the first two conditions are easy, but I don't know if its possible to accomplish the third with Spring. If it is not, maybe I can change it into:

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

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

Do you think it's possible to achieve this? And will performance be good?

谢谢

EDIT:匹配方法的一个示例.如您所见,MyMethod 没有注释(但可以注释).

EDIT: One example of a matching method. As you can see, MyMethod is not annotated (but it can be).

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

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

EDIT: The solution I finally used, based on @Espen answers. As you can see, I changed my conditions a little: class doesn't actually need to be a @Controller.

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

推荐答案

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

It was an interesting problem, so I created a little sample application to solve the case! (And improved it with Sinuhe's feedback afterwards.)

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

I have created a DemoController class that should work as an example for the aspect:

@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 注释参数的方法:

The aspect that will add a join point on the first three methods, but not the last method where the parameter isn't annotated with @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 的类中的所有方法上创建一个连接点.

The first pointcut will create a joinpoint on all methods inside classes marked with @Controller.

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

The second pointcut will add a joinpoint when the following conditions are met:

  • 公共方法
  • first * 是每个返回类型的通配符.
  • second * 是所有类中所有方法的通配符.
  • (.., 在带注释的参数之前匹配零到多个任何类型的参数.
  • @aspects.MyParamAnnotation (*), 匹配使用给定注释进行注释的参数.
  • ..) 在带注释的参数之后匹配零到多个任意类型的参数.
  • public method
  • first * is a wildcard for every return type.
  • second * is a wildcard for all methods in all classes.
  • (.., matches zero to many parameters of any type before the annotated parameter.
  • @aspects.MyParamAnnotation (*), matches a parameter annotated with the given annotation.
  • ..) matches zero to many parameters of any type after the annotated parameter.

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

Finally, the @Before advice advises all methods where all conditions in both pointcuts are satisfied.

切入点适用于 AspectJ 和 Spring AOP!

The pointcut works with both AspectJ and Spring AOP!

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

When it comes to performance. The overhead is small, especially with AspectJ that does the weaving on compile-time or load-time.

这篇关于带注释参数的切入点匹配方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆