儿童对象上的 AspectJ

问题描述 投票:0回答:1

我开始使用 AspectJ,我正在尝试做一些我不知道是否可行的事情。这是我的代码:

public abstract class MyAbstractObject<T> {
    private T myOtherObject;

    public T getMyOtherObject() {
        return myOtherObject;
    }
}

@Component
public class MyObject extends MyAbstractObject<WhateverObject> {
    
}

@Aspect
@Component
public class MyAspects {
    
    @Before("execution(* mypackage.MyAbstractObject.getMyOtherObject().set*(*))")
    public void beforeExample(JoinPoint joinPoint) {
        // DO THINGS
    }
}

此代码失败,错误:

Caused by: java.lang.IllegalArgumentException: Pointcut is not well-formed: expecting ')' at character position 58 execution(* mypackage.MyAbstractObject.getMyOtherObject().set*(*))

但是,我可以像这样拦截 MyOtherObject,但不是它的设置器:

@Aspect
@Component
public class MyAspects {
    
    @Before("execution(* mypackage.MyAbstractObject.getMyOtherObject())")
    public void beforeExample(JoinPoint joinPoint) {
        // DO THINGS
    }
}

我不想到处拦截对象MyOtherObject的setter,因为这个对象在程序中用到的地方比较多,我不需要切面。但是我只想在扩展 MyAbstractObject 的类中使用时拦截它们。

我正在使用 Spring 和 AspectJ。

谢谢。

java spring aspectj spring-aop
1个回答
1
投票

不幸的是,您刚刚发明的语法是非法的。你无法用你想象的方式来描述链式方法调用。

您真正想要的是拦截

WhateverObject
类型的方法执行,而不是
MyAbstractObject
MyObject
的方法执行。也就是说,你的切入点应该下注像

execution(* mypackage.WhateverObject.set*(*))

我只是在猜测,但是如果你想限制匹配以控制从

getMyOtherObject()
(直接或间接)调用 setter 方法的流程,在 AspectJ 中你会添加类似的内容

&& cflow(execution(* mypackage.MyAbstractObject.getMyOtherObject()))

到第一个切入点。但是

cflow
切入点在 Spring AOP 中不可用,这似乎是您正在使用的。所以

  • 要么切换到本机 AspectJ,它很容易 集成到 Spring 应用程序中,但也可以在 Spring 上下文之外使用,因为它是一个独立的产品,
  • 或者您检查 Spring AOP 的 “精简版”控制流切入点 是否满足您的需要。我发布了一些答案和链接,在herethere.
  • 中提到了这个几乎没有记录的功能

作为一个通常不使用 Spring 的原生 AspectJ 粉丝,您可以想象我会推荐哪个选项来控制流切入点,但我认为您可以做出自己的决定。

© www.soinside.com 2019 - 2024. All rights reserved.