Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Doc: @Async in an Interceptor postHandle() doesn't work [SPR-16092] #20641

Closed
spring-projects-issues opened this issue Oct 21, 2017 · 4 comments
Assignees
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: backported An issue that has been backported to maintenance branches type: task A general task
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

Pawan Kumar opened SPR-16092 and commented

If you use a @Async("yourExecutorBeanName") in a method called by an interceptor's postHandle method (whether same class or different class), the Async nature doesn't come into picture, nor does Spring complain for a wrong bean type if doesn't exist by name of "yourExecutorBeanName".

public class EventHandlerInterceptor extends HandlerInterceptorAdapter {

    @Override
    public void postHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler, final ModelAndView modelAndView) throws Exception {
      //some custom logic
      publishSomeEvent(someRequestObj);
    }

    @Async("eventHandlerExecutor")
    public void publishSomeEvent(Request someRequestObj) {
        logger.info("Inside EventHandlerInterceptor - trying for Async.. doesn't work");
        //do something Async.
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        					http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd">

    <!--Default Executor and Schedulers to pick-->
    <task:annotation-driven executor="eventHandlerExecutor"/>
    <task:executor id="eventHandlerExecutor" pool-size="30-40" queue-capacity="40"/><!--Not working inside Interceptor-->

</beans>

Backported to: 4.3.13

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

I'm afraid this is by design: With @EnableAsync and <task:annotation-driven>, the default is proxy-based interception which only actually works when a method call comes in through the proxy: So in your scenario, you'd have to factor out the publishSomeEvent method onto a separate delegate bean which can get independently proxied, with EventHandlerInterceptor injecting a reference to that bean (receiving a proxy) and calling publishSomeEvent through it.

Alternatively, you could also do @EnableAsync(mode=ASPECTJ) and enforce AspectJ-based weaving which allows for intercepting calls within a given object as well, not dealing with a separate proxy. However, this requires a compile-time weaving or load-time weaving setup which seems overkill for your scenario. I'd rather factor out the delegate there, letting a standard proxy arrangements do the job.

That said, we should document this rather common pitfall more clearly. I'm therefore turning this issue into a documentation task.

@spring-projects-issues
Copy link
Collaborator Author

Pawan Kumar commented

Thanks a lot @Juergen. I had indeed tried using a separate @Component bean which had a method doSomethingAsync() and was calling it from EventHandlerInterceptor through @Autowire but it now looks like there was an error in my setup (project re-build most likely) earlier which was preventing the Async to happen. I had tried it multiple times and everything looked right for the setup and should've worked, hence I raised the issue here, rather than SO.
Nevertheless it works now and what you said will indeed work through a proxy. I am ok for the Spring team to resolve this issue and perhaps open a new one for the documentation.
Thanks.

@spring-projects-issues
Copy link
Collaborator Author

Juergen Hoeller commented

Let's simply repurpose this issue for the documentation work: I've added corresponding notes to the javadoc of @EnableAsync, @EnableCaching and @EnableTransactionManagement, as well to the corresponding sections in the reference documentation.

@spring-projects-issues
Copy link
Collaborator Author

Pawan Kumar commented

Sure.

@spring-projects-issues spring-projects-issues added status: backported An issue that has been backported to maintenance branches in: core Issues in core modules (aop, beans, core, context, expression) type: task A general task labels Jan 11, 2019
@spring-projects-issues spring-projects-issues added this to the 5.0.1 milestone Jan 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues in core modules (aop, beans, core, context, expression) status: backported An issue that has been backported to maintenance branches type: task A general task
Projects
None yet
Development

No branches or pull requests

2 participants