2015-05-07 5 views
8

Ich verwende Spring-Anmerkungen für die Konfiguration von Controllern (@EnableWebMvc), Dienste (@service und @ComponentScan). In einem meiner Dienste habe ich eine Methode mit @ Async kommentiert und ich habe auch @EnableAsync in meiner Config-Klasse hinzugefügt. Wenn einer der MVC-Controller die Service-Methode aufruft, die mit @ Asynyn versehen ist, erwarte ich, dass der Controller sofort zurückkehrt, ohne auf die Beendigung der Service-Methode zu warten. Damit nicht. Wenn ich den Unterbrechungspunkt in der Service-Methode einstelle, sehe ich, dass er tatsächlich in einem separaten Thread läuft, d. H. Der Stacktrace zeigt , dass er SimpleAsyncTaskExecutor verwendet, wie ich unten konfiguriert habe. HierSpring MVC-Controller kehrt nicht sofort beim Aufruf von @ Async-Methode zurück

ist die Anmerkung in meiner Konfiguration Klasse sieht aus wie

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

Und hier ist meine MVC Controller-Methode wie

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

aussieht und die Service-Methode sieht wie folgt aus

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

Warum kehrt der MVC-Controller nicht sofort zurück?

+0

Geben Sie die Controller-Klasse ein. Was ist der Rückgabewert? – chrylis

+0

@chrylis Ich habe den Beitrag mit dem Code aus der Controller-Klasse aktualisiert. Bitte überprüfen Sie –

+0

Sie haben den Inhalt der Controller-Methode nicht veröffentlicht. – chrylis

Antwort

0

Meine Vermutung ist, dass Ihre EmailService-Bean aus zwei verschiedenen Kontexten enthalten ist.

Diese answer from Ryan Stewart erklärt das Problem/die Lösung im Detail.

Haben Sie andere Konfigurationen, die verwendet werden? Gibt es in Ihrer web.xml eine * -servlet.xml oder andere Servlets, die Ihren EmailService in den Root-Kontext bringen?

Haben Sie einen ContextLoaderListener oder ServletContextListener definiert? Vielleicht holen diese Ihren EmailService zusätzlich zum Komponentenscan ab.

Einschließlich des gesamten Quellbaums als Komponente-Scan-Pfad scheint verdächtig. Versuchen Sie, die Pfade einzuschränken, die Sie bei der Überprüfung Ihrer Komponente verwenden, um Ihren EmailService auszuschließen und zu sehen, ob er weiterhin in einem SimpleAsyncTaskExecutor ausgeführt wird. Wenn es ist, dann wissen Sie, dass es aus einem anderen Kontext stammt. Sobald Sie den anderen Kontext gefunden haben, können Sie ihn dort ausschließen und ihn zu Ihrem Komponenten-Scan oder EnableAsync in dem anderen Kontext hinzufügen.

+0

Können Sie eine kurze Beschreibung der Lösung bereitstellen? Ansonsten ist dies nur ein Kommentar und keine Antwort. –

Verwandte Themen