java - 如何使用AspectJ(cflow)实现Wormhole模式

标签 java aspectj

我正在尝试使用 AspectJ 和 cflow 开发一个简单的虫洞。

我有两个值对象 Person 和 Account ,如下所示

帐户

public class Account {

    private final String sortCode;
    private final String accountNumber;
    private final int balance;

    public Account(String sortCode, String accountNumber, int balance) {
        this.sortCode = sortCode;
        this.accountNumber = accountNumber;
        this.balance = balance;
    }

    public String getSortCode() {
        return sortCode;
    }

    public String getAccountNumber() {
        return accountNumber;
    }

    public int getBalance() {
        return balance;
    }

    @Override
    public String toString() {
        return "Account{" +
                "sortCode='" + sortCode + '\'' +
                ", accountNumber='" + accountNumber + '\'' +
                ", balance=" + balance +
                '}';
    }
}

public class Person {

    private final String name;
    private final String address;
    private final int age;

    public Person(String name, String address, int age) {
        this.name = name;
        this.address = address;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public String getAddress() {
        return address;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", age=" + age +
                '}';
    }
}

三个“层”

A层

public class Layer_A {

    public void doSomeLevelAprocess(Person person){

        System.out.println("doSomeLevelAprocess person " + person);
        new Layer_B().doSomeLevelBprocess();

    }
}

B层

public class Layer_B {

    public void doSomeLevelBprocess(){

        System.out.println("doSomeLevelBprocess");
        new Layer_C().doSomeLevelCprocess(new Account("123456", "87654321", 1001));

    }
}

C层

public class Layer_C {

    public void doSomeLevelCprocess(Account account){

        System.out.println("doSomeLevelCprocess " );

    }
}

我想要将 Person 对象传递给 Layer_A 方法 doSomeLevelAprocessLayer_C 方法 doSomeLevelCprocess 中可用

这可能吗?

我的样子是这样的

public aspect WormWhole {

    pointcut callerSpace(Person person): execution(* Layer_A.*(..)) && this(person);

    pointcut calleeSpace(Account account): this(account) && execution(public * Layer_C.*(..));

    pointcut wormhole(Person person, Account account):
            cflow(callerSpace(person)) && calleeSpace(account);

    before(Person person, Account account):
            wormhole(person, account){ **//WHAT DO I DO HERE?????** }
}

我是否正确选择了切入点 callerSpace 和 calleeSpace?

需要什么逻辑

before(Person person, Account account):
                wormhole(person, account){ **//WHAT DO I DO HERE?????** }

更新

“可能的重复”问题实际上并没有说明如何实现虫洞,它只是显示了 AspectJ 虫洞的"template"。此外,所提到的问题答案并不试图通过多层传递上下文,这就是虫洞的全部要点。

更新

当我将建议更改为:-

public aspect WormWhole {

    pointcut callerSpace(Person person): execution(* Layer_A.*(..)) && this(person);

    pointcut calleeSpace(Account account): this(account) && execution(public * Layer_C.*(..));

    pointcut wormhole(Person person, Account account):
            cflow(callerSpace(person)) && calleeSpace(account);

    before(Person person, Account account):
            wormhole(person, account){
        System.out.println("Wormhole - " + person);
        System.out.println("Wormhole - " + account);


    }
}

我收到此输出:-

doSomeLevelAprocess person Person{name='aaa', address='aaa', age=19}
doSomeLevelBprocess
doSomeLevelCprocess 

Process finished with exit code 0

这证明我的切入点不正确(我相信),但为什么???

更新

我添加了简单的切入点,效果很好

public aspect WormWhole {

    pointcut callSayHello(): call(* Layer_A.*(..)) || call(* Layer_B.*(..)) || call(* Layer_C.*(..))  ;

    pointcut callerSpace(Person person): execution(* Layer_A.*(..)) && this(person);

    pointcut calleeSpace(Account account): this(account) && execution(public * Layer_C.*(..));

    pointcut wormhole(Person person, Account account):
            cflow(callerSpace(person)) && calleeSpace(account);

    before(Person person, Account account):
            wormhole(person, account){
        System.out.println("Wormhole - " + person);
        System.out.println("Wormhole - " + account);


    }

    after() : callSayHello()  {
        System.out.println("After call sayHello" + thisJoinPoint);
    }
}

测试执行的输出

doSomeLevelAprocess person aaa
doSomeLevelBprocess
doSomeLevelCprocess account 87654321
After call sayHellocall(void Layer_C.doSomeLevelCprocess(Account))
After call sayHellocall(void Layer_B.doSomeLevelBprocess())
After call sayHellocall(void Layer_A.doSomeLevelAprocess(Person))

Process finished with exit code 0

我在 IntelliJ 14.1.14 中使用 CTW,以及 aspectjrt-1.8.6.jar

最佳答案

你是对的,你的切入点出了问题,这就是 AspectJ 编译器显示此警告的原因:

advice defined in Wormhole has not been applied [Xlint:adviceDidNotMatch]   

原因很简单:您尝试通过 this() 而不是 args() 绑定(bind)方法参数。这样两个切入点就无法匹配,因为两个执行上下文中的 this 对象是 Layer_ALayer_C 的实例,而不是 Person帐户

这个小小的改变修复了你的虫洞模式方面:

pointcut callerSpace(Person person) :
    execution(* Layer_A.*(..)) && args(person);

pointcut calleeSpace(Account account) : 
    execution(public * Layer_C.*(..)) && args(account);

关于java - 如何使用AspectJ(cflow)实现Wormhole模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31517759/

相关文章:

java - 禁止 Mule ESB 阻止某些请求

java - 创建匿名动态运行时实例

java - AspectJ 加载时间编织器未检测到所有类

java - joinPoint.proceed() 有什么作用?

java - ClassNotFoundException : org. aopalliance.intercept.MethodInterceptor

java - 找出任何 .jar 包的依赖项

java - 在操作栏中注销

java - 注入(inject)测试

java - AspectJ:两种教程

java - AspectJ - 将接口(interface)实例变量传递给切入点