이벤트 시스템(2) - Guava EventBus를 통한 구현

hyozkim·2020년 2월 14일
1

Guava EventBus를 통한 구현

Guava EventBus 외 Spring의 ApplicationEventPublisher도 사용 가능

guava setup

<pom.xml>

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>${guava.version}</version>
</dependency>

EventConfigure

TaskExecutor - 실제 이벤트를 전달하는 일을 하는 객체
AsyncEventBus - Guava EventBus

-> 이 이벤트버스에 등록, 구독 작업이 수행되는 설정

<EventConfigure.java>

@Configuration
public class EventConfigure {

    @Value("${eventBus.asyncPool.core}")
    private int eventBusAsyncPoolCore;
    @Value("${eventBus.asyncPool.max}")
    private int eventBusAsyncPoolMax;
    @Value("${eventBus.asyncPool.queue}")
    private int eventBusAsyncPoolQueue;

    @Bean
    public TaskExecutor eventTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setThreadNamePrefix("EventBus-");
        executor.setCorePoolSize(eventBusAsyncPoolCore);
        executor.setMaxPoolSize(eventBusAsyncPoolMax);
        executor.setQueueCapacity(eventBusAsyncPoolQueue);
        executor.afterPropertiesSet();
        return executor;
    } // TaskExecutor 작업

    @Bean
    public EventExceptionHandler eventExceptionHandler() {
        return new EventExceptionHandler();
    }

    @Bean
    public EventBus eventBus(TaskExecutor eventTaskExecutor, EventExceptionHandler eventExceptionHandler) {
        return new AsyncEventBus(eventTaskExecutor, eventExceptionHandler); // EventBus 등록
    }

    @Bean(destroyMethod = "close")
    public JoinEventListener joinEventListener(EventBus eventBus, NotificationService notificationService) {
        return new JoinEventListener(eventBus, notificationService); 
    }
}

Fire Event

@Service
public class UserService {
	private final EventBus eventBus;
    public UserService(S3Client s3Client, PasswordEncoder passwordEncoder, UserRepository userRepository, EventBus eventBus) {
    // ...
    this.eventBus = eventBus;
    
    @Transactional
    public User join(String name, Email email, String password, AttachedFile profileFile) {

        String profileImageUrl = uploadProfileImage(profileFile);
        // 이미지 업로드 성공/실패 결과에 관계없이 join 트랜잭션을 처리한다.
        User user = new User(name, email, passwordEncoder.encode(password), profileImageUrl);
        User saved = save(user);

        // raise event
        eventBus.post(new JoinEvent(saved));
        return saved;
    }

Subscribe Event

public class JoinEventListener implements AutoCloseable {

    private Logger log = LoggerFactory.getLogger(JoinEventListener.class);

    private EventBus eventBus;

    public JoinEventListener(EventBus eventBus, NotificationService notificationService) {
        this.eventBus = eventBus;
        eventBus.register(this);
    }

    @Subscribe
    public void handleJoinEvent(JoinEvent event) {
        String name = event.getName();
        Id<User, Long> userId = event.getUserId();
        log.info("user {}, userId {} joined!", name, userId);
    }

    @Override
    public void close() throws Exception {
        eventBus.unregister(this);
    }
}

Configure Listener

@Configuration
public class EventConfigure {
	//...
    @Bean(destroyMethod = "close")
    public JoinEventListener joinEventListener(EventBus eventBus, NotificationService notificationService) {
        return new JoinEventListener(eventBus, notificationService);
    }
}
profile
차근차근 develog

0개의 댓글