Java 基于aspectJ调用方法的参数修改方法的返回类型

Java 基于aspectJ调用方法的参数修改方法的返回类型,java,aop,aspectj,Java,Aop,Aspectj,我需要使用aspectj修改遗留代码方法的返回类型 class MyClass{ public void processTracker(TrackInfo trackInfo) { if (isValid(this.getStatus()) { process(trackInfo); } } boolean isValid(Status status){ ... } } 我希望isValid方法通过TrackIn

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

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

  boolean isValid(Status status){
   ...
  } 
}
我希望
isValid
方法通过
TrackInfo
对象(它被传递给
processTracker
方法)的其他基于逻辑的状态返回true/false

aspecting
processTracker
方法将为我提供parameter,但不会提供修改isValid返回值的选项

@Around("execution(* MyClass.processTracker(..))
aspecting
isValid
将不允许我访问参数
trackInfo

两个方面这是不可能的,因为这段代码运行在多线程。。。 我没有使用Spring,无法向遗留代码添加自定义注释


有什么想法吗?

事实上,你的问题很难理解,可能是因为你的英语水平不是特别好。特别是,我不知道为什么您认为多线程应该是这里的任何问题。也许你可以解释得更详细一点

无论如何,我在这里为您提供两种AOP解决方案:

  • 如果
    if
    条件确实是
    processTracker(TrackInfo)
    中的整个逻辑,则直接从方面调用
    process(TrackInfo)
    ,如示例代码所示。语义上,您只需替换被截取方法的整个逻辑

  • 如果事实上
    processTracker(TrackInfo)
    中有更多的逻辑,并且您的示例代码过于简化,就像外科医生一样,您需要用更细的刀切割,并应用AOP术语中经常被称为虫洞模式的东西

  • 应用程序+助手类:

    由于您的示例代码不完整,我不得不猜测并编写一个示例代码,下次我希望您这样做,因为这实际上是您的工作,而不是我的工作

    package de.scrum\u master.app;
    公共枚举状态{
    有效的,无效的
    }
    
    package de.scrum\u master.app;
    公共类TrackInfo{
    私有字符串信息;
    公共轨迹信息(字符串信息){
    this.info=info;
    }
    公共字符串getInfo(){
    退货信息;
    }
    @凌驾
    公共字符串toString(){
    返回“TrackInfo(“+info+”);
    }
    }
    
    package de.scrum\u master.app;
    导入静态de.scrum_master.app.Status.*;
    公共类MyClass{
    私有状态=有效;
    public void processTracker(TrackInfo TrackInfo){
    if(isValid(getStatus()))
    进程(trackInfo);
    }
    公共作废流程(TrackInfo TrackInfo){
    System.out.println(“处理”+trackInfo);
    }
    私有状态getStatus(){
    如果(状态==有效)
    状态=无效;
    其他的
    状态=有效;
    返回状态;
    }
    布尔值无效(状态){
    返回状态==有效;
    }
    公共静态void main(字符串[]args){
    MyClass MyClass=新的MyClass();
    processTracker(新的TrackInfo(“正常”));
    processTracker(新的TrackInfo(“任何”));
    processTracker(新的TrackInfo(“特殊”));
    }
    }
    
    正如您所看到的,我只是在每次调用中交替使用有效性,从无效到有效再到无效,只是为了在运行main方法时得到不同的结果

    控制台日志为:

    处理跟踪信息(无论什么)
    
    到目前为止,一切顺利。否让我们假设如果
    TrackInfo
    与字符串“special”匹配,我们希望始终假设有效性检查的结果为true

    1。)
    processTracker(TrackInfo)

    package de.scrum\u master.aspect;
    导入org.aspectj.lang.ProceedingJoinPoint;
    导入org.aspectj.lang.annotation.Around;
    导入org.aspectj.lang.annotation.Aspect;
    导入de.scrum_master.app.MyClass;
    导入de.scrum_master.app.TrackInfo;
    @面貌
    公共类simplespect{
    @大约(“执行(*de.scrum_master.app.MyClass.processTracker(..)&&args(trackInfo)&&target(MyClass)”)
    public void modifyValidityCheck(ProceedingJoinPoint thisJoinPoint,TrackInfo TrackInfo,MyClass MyClass)抛出可丢弃{
    if(trackInfo.getInfo().equalsIgnoreCase(“特殊”)){
    //基于某些特殊逻辑的启动处理
    进程(trackInfo);
    }
    否则{
    //正常进行
    thisJoinPoint.procedure();
    }
    }
    }
    
    在这里,我们不需要知道有效性检查的结果是什么,只要在需要时直接调用
    process(TrackInfo)
    。日志输出更改为:

    处理跟踪信息(无论什么)
    处理跟踪信息(特殊)
    
    2.)虫洞模式解决方案

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

    package de.scrum\u master.aspect;
    导入静态de.scrum_master.app.Status.*;
    导入org.aspectj.lang.ProceedingJoinPoint;
    导入org.aspectj.lang.annotation.Around;
    导入org.aspectj.lang.annotation.Aspect;
    导入org.aspectj.lang.annotation.Pointcut;
    导入de.scrum_master.app.Status;
    导入de.scrum_master.app.TrackInfo;
    @面貌
    公共类虫卵{
    @切入点(“执行(*de.scrum_master.app.MyClass.processTracker(..)&&args(trackInfo)”)
    公共静态void processTracker(TrackInfo TrackInfo){}
    @切入点(“执行(*de.scrum\u master.app.MyClass.getStatus()))
    公共静态void getStatus(){}
    @关于(“getStatus()&&cflow(processTracker(trackInfo))”)
    公共状态modifyValidityCheck(ProceedingJoinPoint thisJoinPoint,TrackInfo TrackInfo)抛出Throwable{
    if(trackInfo.getInfo().equalsIgnoreCase(“特殊”)){
    //基于某些特殊逻辑返回true
    返回有效;
    }
    否则{
    //正常进行
    返回(状态)thisJoinPoint.continue();
    }
    }
    }
    
    控制台日志与第一个方面相同,但如果
    processTracker中有更多逻辑(