Инициализация Spring AOP приводит к зависанию всего приложения после нескольких успешных запросов - PullRequest
0 голосов
/ 09 октября 2018

У меня есть приложение Spring 5.0.4 с файлом конфигурации сервлета Dispatcher как spring-web-servlet.xml (spring-web - это имя сервлета Dispatcher).Чтобы включить AOP в приложении, я сделал запись <aop:aspectj-autoproxy /> в spring-web-servlet.xml после включения пространства имен для aop.

В pom.xml есть следующие записи:

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.0.4.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.6.11</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.11</version>
        </dependency>

Для использованияАОП, я создал ниже класс Aspect:

@Aspect
@Component
public class MyAspect {

    @Before("getApiPointcut()")
    public void logRequest(JoinPoint joinPoint) {
      //some logic here
    }

    @AfterReturning(value = "getApiPointcut()", returning = "returnValue")
    public void logResponse(Object returnValue) {
        //some logic here
    }

    @Pointcut("within(com.test.service.controller.*) " +
            " || within(com.test.service.api.GenericService)" +
            " || within(com.test.service.api.UserService)")
    public void getApiPointcut() {

    }


}

Этот класс имеет два метода: logRequest () и logResponse ().Каждый вызов API сначала проходит через logRequest (), и перед возвратом ответа вызывается logResponse ().

Для начальных нескольких запросов (5-6) AOP работает нормально, и я получаю поток в классе MyAspectдля обоих методов.

Но после этого, если я нажму какой-либо API, поток проходит через logRequest (), затем класс API, а затем зависает.Класс API вызывает класс обслуживания.Но поток никогда не достигает класса обслуживания и, следовательно, никогда не входит в logResponse (), и сервер ничего не возвращает клиенту.Я проверил журналы и нет никаких исключений.Я проверил использование памяти кучи тоже, и она не используется полностью.Даже темы не полностью заняты.(Проверил эту статистику с помощью jconsole).

Если я отключу AOP, удалив <aop:aspectj-autoproxy /> из spring-web-servlet.xml файла, сервер вернет ответ на все вызовы без каких-либо проблем.

Итак,Я сделал вывод, что включение AOP приводит к зависанию сервера, но я не могу понять, почему.

Любая помощь приветствуется.

ОБНОВЛЕНИЕ

API (контроллер), для которых я пытаюсь вызвать AOP, помечены @PreAuthorize.Если я закомментирую аннотацию @PreAuthorize, приложение не зависнет.Снятие комментария с аннотации @PreAuthorize снова приводит к 5-6 успешным запросам, а затем приложение зависает.Поскольку @PreAuthorize также использует AOP, есть ли какой-то случай, о котором мне нужно позаботиться, когда я использую свой собственный AOP с @PreAuthorize?

UPDATE 2

The @PreAuthorizeМетод API выглядит следующим образом:

@PreAuthorize("hasAuthority('SOME_AUTH') and @myUtil.canRead(#userId) ")

Если я удаляю hasAuthority('SOME_AUTH') и сохраняю вторую проверку, приложение работает нормально, но если я сохраню обе или оставлю только проверку hasAuthority (), приложениене отвечает после нескольких успешных ответов.

ОБНОВЛЕНИЕ 3

Проблема будет решена, если я аннотирую API с помощью @Transactional.Однако код работал без @Transactional, когда aop был отключен.Так почему включение AOP делает необходимым наличие @Transactional в API?

...