几次成功请求后,初始化Spring AOP会挂起整个应用程序

时间:2018-10-09 07:37:50

标签: java spring spring-mvc aop aspectj

我有一个Spring 5.0.4应用程序,其Dispatcher servlet配置文件为spring-web-servlet.xml(spring-web是Dispatcher servlet名称)。 为了在应用程序中启用AOP,在包含aop的名称空间之后,我在<aop:aspectj-autoproxy />中创建了条目spring-web-servlet.xml

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>

要使用AOP,我在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:aspectj-autoproxy />文件中删除spring-web-servlet.xml来禁用AOP,则服务器将返回所有呼叫的响应,而不会出现任何问题。

因此,我得出的启用AOP的结论导致服务器挂起,但我无法理解原因。

感谢您的帮助。

更新

我要在其上调用AOP的API(控制器)用@PreAuthorize注释。如果我注释掉@PreAuthorize批注,则该应用程序不会挂起。再次取消对@PreAuthorize注释的注释会导致5-6个成功的请求,然后应用程序挂起。 由于@PreAuthorize也使用AOP,因此在将我自己的AOP与@PreAuthorize一起使用时,是否需要处理任何情况?

更新2

API上的@PreAuthorize方法如下:

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

如果我删除hasAuthority('SOME_AUTH')并保留第二个检查,则应用程序工作正常,但是如果我同时保留或仅保留hasAuthority()检查,则应用程序在几次成功响应后不会响应。

更新3

如果我使用@Transactional注释API,此问题将得到解决。 但是,禁用aop时,该代码过去无需@Transactional即可工作。那么为什么启用AOP使得必须在API上使用@Transactional?

0 个答案:

没有答案