2015-05-07 2 views
8

Я использую весенние аннотации для настройки контроллеров (@EnableWebMvc), сервисов (@service и @ComponentScan). В одной из моих служб у меня есть метод, аннотированный с @Async, и у меня также есть @EnableAsync, добавленный в мой класс конфигурации. Когда один из контроллеров MVC вызывает метод службы, который аннотируется с @Async, я ожидаю, что контроллер немедленно вернется, не дожидаясь завершения метода службы. Это не так. Когда я настраиваю точку прерывания в методе службы, я вижу, что она фактически выполняется в отдельном потоке, то есть в стеке trace отображается , что он использует SimpleAsyncTaskExecutor, как я настроил ниже.Контроллер Spring MVC не возвращается сразу при вызове метода @Async

Вот аннотаций в моем классе конфигурации выглядит

@Configuration 
@EnableWebMvc 
@EnableScheduling 
@ComponentScan(basePackages = "com.mypackage") 
@EnableAsync 
public class WebApplicationConfig extends WebMvcConfigurerAdapter implements AsyncConfigurer { 
... 
... 
@Override 
    public Executor getAsyncExecutor() { 
     SimpleAsyncTaskExecutor executor = new SimpleAsyncTaskExecutor("SimpleExecutor-"); 
     executor.setConcurrencyLimit(props.getIntegerProperty(SysProps.EMAIL_SENDER_CONCURRENT_THREAD_LIMIT)); 
     return executor; 
    } 

И вот мой метод контроллера MVC выглядит

@Autowired 
    private EmailService emailService; 
    @ResponseStatus(value = HttpStatus.CREATED) 
    @RequestMapping(value = "/asset/{assetId}/slideshare/email", method = RequestMethod.POST, produces = JSON_UTF8) 
    @ResponseBody 
    @ApiResponseObject 
    public Link createAndEmailSlideShareLink(@PathVariable final String assetId, 
              @RequestParam(value = "email") final String email, 
              @RequestParam(value = "message", required = false) final String message, 
              final HttpServletRequest request) { 
    Link link = linkService.createLink() 
    emailService.sendSlideShareAssetEmail(user,link... 
    return link; 
} 

И метод обслуживания выглядит следующим образом

@Async 
public void sendSlideShareAssetEmail(User user, String email, String msg, String link, Asset asset) { 

Почему контроллер MVC не возвращается сразу?

+0

Опубликовать класс контроллера. Какова обратная стоимость? – chrylis

+0

@chrylis Я обновил сообщение с кодом из класса контроллера. Пожалуйста, проверьте –

+0

Фактически вы не публикуете содержание метода контроллера. – chrylis

ответ

0

Я предполагаю, что ваш компонент EmailService включен из двух разных контекстов.

Этот answer from Ryan Stewart более подробно описывает проблему/решение.

У вас есть другие настройки, которые используются? Есть ли в вашем web.xml * -servlet.xml или другие сервлеты, которые могут привести ваш EmailService в корневой контекст?

У вас есть определенный ContextLoaderListener или ServletContextListener? Возможно, они собирают ваш EmailService в дополнение к сканированию компонентов.

Включает в себя все исходное дерево, поскольку путь отслеживания компонентов кажется подозрительным. Попробуйте ограничить пути, которые вы используете в сканировании компонентов, чтобы исключить ваш EmailService и посмотреть, работает ли он все еще в SimpleAsyncTaskExecutor. Если это так, как вы знаете, что его приводят из другого контекста. После того, как вы найдете другой контекст, вы сможете исключить его и добавить его обратно в компонент-сканирование или EnableAsync в другом контексте.

+0

Можете ли вы предоставить краткое описание решения? В противном случае это только комментарий, а не ответ. –

 Смежные вопросы

  • Нет связанных вопросов^_^