覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

Spring Boot - 非同期処理を簡単に書く

Spring Bootでアプリケーション構築をする際に、@Asyncorg.springframework.scheduling.annotation.Async)アノテーションを利用することで簡単に非同期処理を記述することができます。

以下サンプルです
監査ログを書き込むためのAuditLoggerを定義して、そこで行うロギング処理を非同期で実行する例です


■非同期処理のTaskExecutorの定義

非同期処理有効にするために@EnableAsyncアノテーションをクラスに付与します

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

@Configuration
@EnableAsync
class AsyncConfig {

    @Bean("auditLogger")
    public TaskExecutor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(1);
        executor.setMaxPoolSize(1);
        executor.setQueueCapacity(200);
        executor.setThreadNamePrefix("AuditLogger");

        return executor;
    }
}


■非同期処理で実行したいメソッド

非同期処理で実行したいメソッドに@Asyncを付与します。

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;


@Service
@Slf4j
class AuditLoggerImpl implements AuditLogger {

    private final AuditLogRepository auditLogRepository;

    @Autowired
    public AuditLoggerImpl(AuditLogRepository auditLogRepository) {
        this.auditLogRepository = auditLogRepository;
    }

    @Async("auditLogger")
    @Override
    public void log(AuditLog auditLog) {
        auditLogRepository.register(auditLog);

        log.info("audit logged. {}", auditLog);
    }
}

上記のコードを書いておくと@Asyncを付与したメソッドが自動的に非同期で実行されます。
処理実行時には@Asyncのパラメータに指定した値と同じ名前でBean定義したTaskExecutorが利用されます。