AspectJ:我可以中和'throw'(用日志替换它)并继续该方法

时间:2011-08-19 07:03:58

标签: aspectj

在下面的代码中,我想中和throw并继续方法 - 可以这样做吗?

public class TestChild extends TestParent{

private String s; 

public void doit(String arg) throws Exception {

    if(arg == null) {
        Exception e  = new Exception("exception");

        throw e;
    }
    s=arg;
}

}

如果触发了异常(arg == null)

,最终结果应该是这样
  1. throw e由Log(e)
  2. 取代
  3. s = arg已执行
  4. 由于

    PS:我可以“吞下”异常或用另一个异常替换它,但在所有情况下方法都不会继续,我的所有干预都会在损害发生时发生(即抛出异常)

2 个答案:

答案 0 :(得分:0)

我强烈怀疑存在一般解决方案。但是对于您的特定代码和要求1和2:

privileged public aspect SkipNullBlockAspect {


public pointcut needSkip(TestChild t1, String a1): execution(void TestChild.doit(String)) 
    && this(t1) && args(a1) ;


void around(TestChild t1, String a1): needSkip(t1, a1){             
    if(a1==null) //if argument is null - doing hack.
    {
        a1="";      //alter argument to skip if block.  
        proceed(t1, a1);

        t1.s=null;
        a1=null;    //restore argument
        System.out.println("Little hack.");
    }
    else
        proceed(t1, a1);    

}

}

答案 1 :(得分:0)

我认为通常你想要的东西在大多数情况下都没有意义,因为如果一个应用程序抛出一个异常就有理由这样做,而且这个原因几乎总是包含意图而不是继续由于伪造数据可能导致的后续错误而抛出异常的方法的正常控制流程。例如,如果您可以中和代码中的throw并且下一行代码会执行以下操作,该怎么办:

if(arg == null)
    throw new Exception("exception");

// We magically neutralise the exception and are here with arg == null

arg.someMethod();                         // NullPointerException
double x = 11.0 / Integer.parseInt(arg);  // NumberFormatException
anotherMethod(arg);                       // might throw exception if arg == null

你明白了吗?假设你可以,你可以通过继续控制流程来承担不可估量的风险。现在替代方案是什么?

  • 让我们假设你确切知道null的值在这里没有任何伤害。那么为什么不用after() throwing建议来捕获异常?
  • 或者如果null有害并且你知道它,为什么不拦截方法执行并覆盖参数以避免开始的异常?
  • 推测假设方法内容对你来说是一个黑盒子而你正试图在这里做一些hacky事情,你可以使用around()建议,然后用不同的参数多次调用proceed()值(例如某些身份验证令牌或密码),直到被调用的方法不再抛出异常。

如您所见,有很多方法可以解决您的实际问题,具体取决于问题究竟是什么以及您想要实现的目标。

说完这一切之后,现在让我们回到捕捉的初始技术问题,但实际上中和异常,即某种方式避免被扔掉。因为AspectJ语言不包含执行您想要的技术手段(感谢上帝!),您可以查看其他可以以更低级别的方式操作Java类文件的工具。我从来没有高效地使用它们,但我很确定你可以使用BCELJavassist做你想做的事。

相关问题