2016-05-12 13 views
3

Versuchen, asynchrone Ereignisbehandlung zu aktivieren, die die @Async- und -Annotationen kombiniert, aber ich sehe immer noch, dass der Listener im Publizierungsthread ausgeführt wird.@EventListener mit @ Async im Frühjahr

Das Beispiel finden Sie hier:

@SpringBootApplication 
@EnableAsync 
class AsyncEventListenerExample { 

static final Logger logger = LoggerFactory.getLogger(AsyncEventListenerExample.class); 

@Bean 
TaskExecutor taskExecutor() { 
    return new SimpleAsyncTaskExecutor(); 
} 


static class MedicalRecordUpdatedEvent { 

    private String id; 

    public MedicalRecordUpdatedEvent(String id) { 
     this.id = id; 
    } 

    @Override 
    public String toString() { 
     return "MedicalRecordUpdatedEvent{" + 
       "id='" + id + '\'' + 
       '}'; 
    } 
} 

@Component 
static class Receiver { 

    @EventListener 
    void handleSync(MedicalRecordUpdatedEvent event) { 
     logger.info("thread '{}' handling '{}' event", Thread.currentThread(), event); 
    } 

    @Async 
    @EventListener 
    void handleAsync(MedicalRecordUpdatedEvent event) { 
     logger.info("thread '{}' handling '{}' event", Thread.currentThread(), event); 
    } 

} 

@Component 
static class Producer { 

    private final ApplicationEventPublisher publisher; 

    public Producer(ApplicationEventPublisher publisher) { 
     this.publisher = publisher; 
    } 

    public void create(String id) { 
     publisher.publishEvent(new MedicalRecordUpdatedEvent(id)); 
    } 

    @Async 
    public void asynMethod() { 
     logger.info("running async method with thread '{}'", Thread.currentThread()); 
    } 
} 

} 

und mein Testfall:

@RunWith(SpringRunner.class) 
@SpringBootTest(classes = AsyncEventListenerExample.class) 
public class AsyncEventListenerExampleTests { 

@Autowired 
Producer producer; 

@Test 
public void createEvent() throws InterruptedException { 

    producer.create("foo"); 

    //producer.asynMethod(); 


    // A chance to see the logging messages before the JVM exists. 
    Thread.sleep(2000); 

} 
} 

jedoch in Protokollen sehe ich, dass beide @EventListener s im main Thread ausgeführt.

2016-05-12 08:52:43.184 INFO 18671 --- [   main] c.z.e.async2.AsyncEventListenerExample : thread 'Thread[main,5,main]' handling 'MedicalRecordUpdatedEvent{id='foo'}' event 
2016-05-12 08:52:43.186 INFO 18671 --- [   main] c.z.e.async2.AsyncEventListenerExample : thread 'Thread[main,5,main]' handling 'MedicalRecordUpdatedEvent{id='foo'}' event 

async Die Infrastruktur ist mit @EnableAsync mit einem asynchronen TaskExecutor initialisiert.

Nicht sicher, was ich falsch mache. Könntest du helfen?

Danke.

mit Spring-Boot 1.4.2.M2, so Frühling 4.3.0.RC1

Antwort

1

Es gibt eine Regression in Spring Framework war 4.3.0.RC1, die sehr zu, dass führt Problem Sie haben. Wenn Sie den SNAPSHOT verwenden, läuft Ihr Projekt gut.

1

onTicketUpdatedEvent läuft auch im Hauptfaden mit Federrahmen 4.2.4 Freigabe wie folgt. Aber es läuft in SimpleAsyncTaskExecutor, wenn AsyncConfigurer nicht implementiert ist.

@EnableAsync(proxyTargetClass = true) 
@Component 
@Slf4j 
public class ExampleEventListener implements AsyncConfigurer { 

    @Async 
    @EventListener 
    public void onTicketUpdatedEvent(TicketEvent ticketEvent) { 
     log.debug("received ticket updated event"); 
    } 

    @Override 
    public Executor getAsyncExecutor() { 
     ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 
     executor.setMaxPoolSize(100); 
     executor.initialize(); 
     return executor; 
    } 

    @Override 
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { 
     return null; 
    } 
} 
1

Ich löste mein Problem durch Konfigurieren von Task-Executor Bean wie folgt.

@Bean(name = "threadPoolTaskExecutor") 
public Executor getAsyncExecutor() { 
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 
    executor.setMaxPoolSize(100); 
    executor.initialize(); 
    return executor; 
} 

@Async("threadPoolTaskExecutor") 
@EventListener 
public void onTicketUpdatedEvent(TicketEvent ticketEvent) { 
    log.debug("received ticket updated event"); 
}