多个@Around AspectJ在同一个连接点上

时间:2015-12-07 22:03:20

标签: java spring aop aspect

我有两个不同的Aspect类,方面类1将处理将在我的所有控制器文件中发生的任何异常,另一个方面类2将处理仅在一个特定控制器文件中发生的少数特定异常。我已经指定了优先顺序,为aspect2提供了优先于aspect1的优先级。 Aspect class 1如下

@Aspect
@Order(1)
public class TrackOperations {
@Around("apiPointcut()")
public Object handleException(ProceedingJoinPoint pjp) throws Throwable {
    try {
        return pjp.proceed();
    } catch (Exception e) {
        LOGGER.error("Caught exception: ", e);
        StringBuilder sb = getExceptionTrace(e);
        StringWriter errorStackTrace = new StringWriter();
        e.printStackTrace(new PrintWriter(errorStackTrace, true));
        response.addError(error);
        return new ResponseEntity<String>(JsonUtil.toJson(response), HttpStatus.INTERNAL_SERVER_ERROR);
    }} 

Aspect class 2

@Aspect
@Order(0)
public class TrackServiceOperations {
@Around("apiPointcut()")
public Object handleServerException(
    try {
        return pjp.proceed();

    } catch (HttpClientErrorException | HttpServerErrorException e) {
        response = (Response<String>) ContextUtil.get(key);
        response.addError(new Error("Assessment Service Status Code: " + e.getStatusCode(), ErrorConstants.REQUEST_FAILED));
        LOGGER.error("Recieved" + e.getStatusCode() + " status from Assessment Service");
        return new ResponseEntity<String>(JsonUtil.toJson(response), HttpStatus.OK);
    }
}}

在应用程序xml中提到了相同的内容

<bean    id="TrackServiceOperations" class="in.foo.foo.TrackServiceOperations" factory-method="aspectOf" />
<bean   id="TrackOperations" class="in.foo.foo.TrackOperations" factory-method="aspectOf" />

但是当控制器文件抛出所需的异常时,方面类1最终会处理异常而不是方面类2.当我禁用方面类1时,事情会按预期正常工作,但是当我同时使用@around切入点时,优先顺序似乎不起作用。我在这里错过了什么吗?

2 个答案:

答案 0 :(得分:1)

方面类1正在处理HttpClientErrorException和HttpServerErrorException派生自的泛型异常。因此,当您想要在方面类2中处理异常时,它们已经被方面类1的处理程序所覆盖。

要修复,你可以检查方面类1处理程序中的异常类型,并重新抛出你想要在方面2中处理的那些特殊异常。(这感觉就像一个kludge,因为它现在有方面1知道方面的内容2)。

public Object handleException(ProceedingJoinPoint pjp) throws Throwable {
try {
    return pjp.proceed();
} catch (Exception e) {
    (if e instance of org.springframework.web.client.HttpStatusCodeException || e instanceof org.springframework.web.client. HttpServerErrorException) throw e;

    LOGGER.error("Caught exception: ", e);
    StringBuilder sb = getExceptionTrace(e);
    StringWriter errorStackTrace = new StringWriter();
    e.printStackTrace(new PrintWriter(errorStackTrace, true));
    response.addError(error);
    return new ResponseEntity<String>(JsonUtil.toJson(response), HttpStatus.INTERNAL_SERVER_ERROR);
}} 

答案 1 :(得分:0)

能够通过在同一个方面类中添加切入点而不是不同的方面类来解决这个问题。