2015-05-07 2 views
8

Utilizzo annotazioni a molla per la configurazione di controller (@EnableWebMvc), servizi (@service e @ComponentScan). In uno dei miei servizi ho un metodo annotato con @Async e ho aggiunto anche @EnableAsync sulla mia classe di configurazione. Quando uno dei controller MVC chiama il metodo di servizio annotato con @Async, mi aspetto che il controller torni immediatamente senza attendere il completamento del metodo di servizio. Per non farlo. Quando imposto il punto di interruzione nel metodo di servizio, vedo che in effetti è in esecuzione in un thread separato, ovvero lo stacktrace mostra che sta utilizzando SimpleAsyncTaskExecutor come configurato di seguito.Spring Il controller MVC non viene restituito immediatamente quando si chiama il metodo @Async

Ecco l'annotazione nella mia classe di configurazione assomiglia

@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; 
    } 

E qui è il mio metodo di controllo MVC sembra

@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; 
} 

E il metodo di servizio simile a questo

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

Perché il controller MVC non viene restituito immediatamente?

+0

Invia la classe controller. Qual è il valore di ritorno? – chrylis

+0

@chrylis Ho aggiornato il post con il codice della classe controller. Si prega di verificare –

+0

Non hai effettivamente pubblicato il contenuto del metodo del controller. – chrylis

risposta

0

La mia ipotesi è che il bean di EmailService venga incluso da due diversi contesti.

Questo answer from Ryan Stewart spiega il problema/soluzione in modo più dettagliato.

Avete altre configurazioni in uso? Esiste un * -servlet.xml o altri servlet definiti nel tuo web.xml che potrebbero portare il tuo EmailService nel contesto di root?

Avete definito ContextLoaderListener o ServletContextListener? Forse questi stanno raccogliendo il tuo EmailService in aggiunta alla scansione dei componenti.

Includere l'intero albero di origine come il percorso di scansione componente sembra sospetto. Provare a limitare i percorsi che si utilizzano nella scansione del componente per escludere il proprio EmailService e verificare se è ancora in esecuzione in un SimpleAsyncTaskExecutor. Se è così, sai che è stato portato da un contesto diverso. Una volta trovato l'altro contesto, dovresti essere in grado di escluderlo e aggiungerlo nuovamente al componente-scan o EnableAsync nell'altro contesto.

+0

Potete fornire una breve descrizione della soluzione? Altrimenti questo è solo un commento e non una risposta. –