несколько @Around AspectJ на одной и той же точке соединения

У меня есть два разных класса аспектов, класс аспекта 1 позаботится о любых исключениях, которые могут возникнуть во всех моих файлах контроллера, а другой, класс аспекта 2, будет обрабатывать несколько конкретных исключений, которые могут возникнуть только в одном конкретном файле контроллера. Я указал порядок приоритета, дав аспекту класса 2 более высокий приоритет, чем аспекту1. Аспект класса 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);
    }} 

Аспект класса 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, все работает нормально, как и ожидалось, но когда я использую оба @round pointcuts, порядок приоритета не работает. Я что-то упустил здесь?


person Crane    schedule 07.12.2015    source источник


Ответы (2)


класс аспекта 1 обрабатывает общее исключение, из которого происходят как HttpClientErrorException, так и HttpServerErrorException. Таким образом, к тому времени, когда вы захотите, чтобы исключения обрабатывались в классе аспекта 2, они уже были охвачены обработчиком класса аспекта 1.

Чтобы исправить это, вы можете проверить тип исключения в обработчике класса аспекта 1 и повторно сгенерировать те специальные исключения, которые вы хотите обработать в классе аспекта 2. (Это похоже на кладж, поскольку теперь аспект 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);
}} 
person pdmoore    schedule 08.12.2015
comment
Спасибо за предложение. Но в идеале это должно решаться по приоритету, верно? Я все равно исправил это, добавив точечный разрез в один и тот же класс аспектов вместо двух разных классов. - person Crane; 08.12.2015
comment
Да, я думаю, приоритет - правильный способ исправить это. Я бросил это там как обходной путь. - person pdmoore; 09.12.2015

Удалось исправить это, добавив pointcut в тот же класс аспектов, а не в другой класс аспектов.

person Crane    schedule 08.12.2015