已解决java.lang.IllegalStateException: No MethodInvocation found: Check that an AOP invocation

抛出异常后通知AfterThrowing切面后Controller无法捕获Service抛出的异常类型,但可以捕获Exception或Throwable,获取异常信息提示如下:

 java.lang.IllegalStateException: No MethodInvocation found: Check that an AOP invocation is in progress, 
and that the ExposeInvocationInterceptor is upfront in the interceptor chain. Specifically, 
note that advices with order HIGHEST_PRECEDENCE will execute before ExposeInvocationInterceptor! 

当切点service方法抛出异常后,切面类LogInterceptor 的throwing方法会正常执行,但Controller里却无法捕获ValidateException 异常,通过捕获Exception异常后,报出文上错误信息,经查看源码发现,是源码ExposeInvocationInterceptor类中抛出了新异常IllegalStateException,源码如下:


spring配置如下:
    <bean id="logInterceptor" class="xx.xxx.xxx.LogInterceptor"></bean>
    <aop:config>
        <aop:aspect id="logAspectSYS" ref="logInterceptor" order="1">
            <aop:after-throwing method="throwing" throwing="ex" pointcut="execution(public * xx.xxx.xxx..*.*(..))" />
        </aop:aspect>
    </aop:config>

切面类如下:
public class LogInterceptor {

static Log logger = LogFactory.getLog(LogInterceptor.class);

public void throwing(JoinPoint joinPoint, Throwable ex) {
StackTraceElement[] stack =  ex.getStackTrace();

logger.error("异常信息:" + (ex.getMessage() == null ? "" : ex.getMessage()));  

logger.error("{");
logger.error("\t" + ex.getClass().getName());
for(int i = 0; i < stack.length; i++){
logger.error("\t" + stack[i]);
}
logger.error("}");
}
}

Service切点方法如下:
 public int saveFinancialPlan(String applyIds,Double amount,Integer days,Double interest,Integer raiseDays,Integer releaseType,Date releaseTime)  throws ValidateException{
throw new ValidateException("发生异常了");
}

Controller方法如下
 @RequestMapping(value = "saveFinancialPlan")
    public @ResponseBody OperateResult saveFinancialPlan(String applyIds,Double amount,Integer days,Double interest,Integer raiseDays,Integer releaseType,Date releaseTime, Model model){
   try {
   financePlanService.saveFinancialPlan(applyIds,amount,days,interest,raiseDays,releaseType,releaseTime);
   } catch (ValidateException e) {
  return new OperateResult(OperateResultType.Error,e.getMessage());
   }
   return new OperateResult(OperateResultType.Success);
    }


研究很久也没弄清原因。可以肯定,配置方面没有问题。

但,问题总要解决啊,抱着试试的态度,居然奇迹般的解决了。解决办法就是,去掉所有xml配置的切面编程,改用AspectJ注解的方式。具体如下

xml配置:
<context:component-scan base-package="xx.xx.xxx" />  <!--扫描所有注解的包-->
<aop:aspectj-autoproxy/>                                               <!--打开aop注解-->   

切面类如下:
@Component
@Aspect
public class LogInterceptor {

static Log logger = LogFactory.getLog(LogInterceptor.class);

@Pointcut("execution(public * xx.xxx.xxx..*.*(..))")
public void pointcut(){}

@AfterThrowing(pointcut = "pointcut()",throwing = "ex")
public void throwing(JoinPoint joinPoint, Throwable ex) {
StackTraceElement[] stack =  ex.getStackTrace();

logger.error("异常信息:" + (ex.getMessage() == null ? "" : ex.getMessage()));  

logger.error("{");

logger.error("\t" + ex.getClass().getName());

for(int i = 0; i < stack.length; i++){
logger.error("\t" + stack[i]);
}
logger.error("}");
}
}

如此,就解决了问题,再也没有报上文的错误,切面类也很好的实现了功能。

但,为什么xml配置的切面编程就无法实现呢?欢迎大神解答,多谢!

发布了3 篇原创文章 · 获赞 0 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qingrunhao/article/details/53102511
今日推荐