基于与AspectJ的呼叫方法的参数方法的修改返回类型

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

我需要修改的使用AspectJ遗留代码的方法的返回类型。

class MyClass{
   public void processTracker(TrackInfo trackInfo) {        
     if (isValid(this.getStatus()) {
        process(trackInfo);
     }
   }

  boolean isValid(Status status){
   ...
  } 
}

我想isValid方法通过TrackInfo对象的某些其他逻辑基础状态(被传递参数processTracker方法)返回真/假

aspecting processTracker方法会给我paramaeter但不会放弃选项来修改isValid方法的返回值

@Around("execution(* MyClass.processTracker(..))

aspecting isValid不会给我访问参数trackInfo

2个方面这段代码运行时,它是不可能的多线程...我没有使用弹簧,不能自定义的注释添加到遗留代码。

有任何想法吗?

java aspectj
1个回答
1
投票

其实,你的问题是很难理解,也许是因为你的英语水平不是特别好。特别是,我不知道为什么你认为多线程应该是没有什么问题在这里。也许你可以解释说,在更详细一点。

不管怎么说,我在这里提供你俩AOP的解决方案:

  1. 只需直接调用process(TrackInfo)从方面如果if条件真的是processTracker(TrackInfo)整个逻辑,你的代码示例所示。在语义上,您只需更换截获方法的整个逻辑。
  2. 如果有,其实更多的逻辑processTracker(TrackInfo)内和示例代码是过于简单化,像外科医生就需要剪更精细的切开刀,并应用在什么方面AOP常常引用作为一个虫洞模式。

应用+辅助类:

因为你的示例代码是不完整的,我猜和弥补的MCVE,我希望它下一次你做,因为它实际上是你的工作,不是我的。

package de.scrum_master.app;

public enum Status {
    VALID, INVALID
}
package de.scrum_master.app;

public class TrackInfo {
  private String info;

  public TrackInfo(String info) {
    this.info = info;
  }

  public String getInfo() {
    return info;
  }

  @Override
  public String toString() {
    return "TrackInfo(" + info + ")";
  }
}
package de.scrum_master.app;

import static de.scrum_master.app.Status.*;

public class MyClass {
  private Status status = VALID;

  public void processTracker(TrackInfo trackInfo) {
    if (isValid(getStatus()))
      process(trackInfo);
  }

  public void process(TrackInfo trackInfo) {
    System.out.println("Processing " + trackInfo);
  }

  private Status getStatus() {
    if (status == VALID)
      status = INVALID;
    else
      status = VALID;
    return status;
  }

  boolean isValid(Status status) {
    return status == VALID;
  }

  public static void main(String[] args) {
    MyClass myClass = new MyClass();
    myClass.processTracker(new TrackInfo("normal"));
    myClass.processTracker(new TrackInfo("whatever"));
    myClass.processTracker(new TrackInfo("special"));
  }
}

正如你所看到的,我只是从交替无效的有效和背部与每一个电话的有效性,只是运行的主要方法时得到不同的结果。

控制台日志:

Processing TrackInfo(whatever)

到现在为止还挺好。没有让我们假设,如果TrackInfo字符串“特殊”的比赛,我们要始终承担有效性检查结果为true。

1.)纵横替换processTracker(TrackInfo)的逻辑

package de.scrum_master.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

import de.scrum_master.app.MyClass;
import de.scrum_master.app.TrackInfo;

@Aspect
public class SimpleAspect {
  @Around("execution(* de.scrum_master.app.MyClass.processTracker(..)) && args(trackInfo) && target(myClass)")
  public void modifyValidityCheck(ProceedingJoinPoint thisJoinPoint, TrackInfo trackInfo, MyClass myClass) throws Throwable {
    if (trackInfo.getInfo().equalsIgnoreCase("special")) {
      // Kick off processing based on some special logic
      myClass.process(trackInfo);
    }
    else {
      // Proceed normally
      thisJoinPoint.proceed();
    }
  }
}

在这里,我们并不需要知道什么有效性检查将评估为,但如果需要的话就叫process(TrackInfo)直接。日志输出更改为:

Processing TrackInfo(whatever)
Processing TrackInfo(special)

2.)虫洞图案溶液

在这里,我们实际上从拉调用方法TrackInfo作为上下文信息processTracker(TrackInfo)isValid(Status status),所以我们可以在必要时直接修改有效性检查结果。

package de.scrum_master.aspect;

import static de.scrum_master.app.Status.*;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

import de.scrum_master.app.Status;
import de.scrum_master.app.TrackInfo;

@Aspect
public class WormholePatternAspect {
  @Pointcut("execution(* de.scrum_master.app.MyClass.processTracker(..)) && args(trackInfo)")
  public static void processTracker(TrackInfo trackInfo) {}

  @Pointcut("execution(* de.scrum_master.app.MyClass.getStatus())")
  public static void getStatus() {}

  @Around("getStatus() && cflow(processTracker(trackInfo))")
  public Status modifyValidityCheck(ProceedingJoinPoint thisJoinPoint, TrackInfo trackInfo) throws Throwable {
    if (trackInfo.getInfo().equalsIgnoreCase("special")) {
      // Return true based on some special logic
      return VALID;
    }
    else {
      // Proceed normally
      return (Status) thisJoinPoint.proceed();
    }
  }
}

控制台日志相同与第一方面,但是如果有processTracker(TrackInfo)内更多的逻辑,它的其余部分也将被执行时,不切断(取代)如在第一方面中。

随你挑。我建议一起去(如果适用)简单的解决方案。虫洞图案优雅,但更难理解,需要运行时调用堆栈分析,由于cflow(),因此它应该是稍微慢一点为好。

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