2016-05-12 4 views
3

@Async@EventListenerアノテーションを組み合わせた非同期イベント処理を有効にしようとしていますが、依然としてリスナーがパブリッシュスレッドで実行されていることがわかります。@EventListener、Springで@Asyncを使用する

あなたがここで見つけることができます例:

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

} 

と私のテストケース:

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

} 
} 

をしかし、私は両方の@EventListener sがmainスレッドで実行することを参照してログに。

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インフラは、非同期TaskExecutor@EnableAsyncで初期化されます。

私が間違っていることがわかりません。手伝ってくれる?

ありがとうございました。春ブーツ1.4.2.M2を使用して

、非常にあなたが持っている問題ことにつながるのSpring Frameworkの4.3.0.RC1での回帰がありました春4.3.0.RC1

答えて

1

そう。 SNAPSHOTを使用すると、プロジェクトは正常に動作します。

1

onTicketUpdatedEvent Spring Framework 4.2.4リリースのメインスレッドでも実行されます。 AsyncConfigurerが実装されていない場合、SimpleAsyncTaskExecutorで実行されます。

@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

私は、task-executor beanを次のように構成することで問題を解決しました。

@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"); 
} 
関連する問題