자바생
728x90

YAPP 프로젝트를 진행하는 중에 현재 시간 기준으로 모임 종료 시간이 지났을 경우 모임을 종료시켜야 할 필요가 있었다

해당 기능은 스프링에서 제공하는 @Scheduled를 이용하여 구현할 수 있었다

 

스케줄러를 어떻게 사용했는지 기록한다

 

Implementation

  • 현재 시간 기준으로 모임 종료 시간이 지났을 경우 모임을 종료시켜야 한다

 

How

  • 모임 종료 시간이 현재 시간보다 지나있을 경우 모임의 status를 모임 종료로 변경
  • 스프링에서 제공하는 스케줄러를 사용해보자!

 

Scheduling 적용

 

@EnableScheduling

  • SpringBootApplication이 붙은 클래스에 @EnableScheduling을 붙인다
@EnableJpaAuditing
@SpringBootApplication
@EnableScheduling
public class PetApplication {

   public static void main(String[]args) {
      SpringApplication.run(PetApplication.class,args);
   }

}

 

Scheduler.class 생성

  • 스케줄러 관련 클래스를 생성한다
  • 해당 클래스 빈 등록을 해줘야 하기 때문에 @Component를 붙인다
  • ClubService를 통해 종료시간이 지났지만 모임의 상태가 AVAILABLE 한 모임을 조회하여 모두 END로 변경한다
  • 해당 api는 1분마다 실행한다
@Component
@RequiredArgsConstructor
public class Scheduler {

    private final ClubService clubService;

    @Scheduled(cron = "0 * * * * *")
    public void exceedClub() {
        clubService.exceedTimeClub()
                   .forEach(club -> {
                       club.updateStatus(ClubStatus.END);
                   });
    }
}

 

@Scheduled 옵션 중 cron은 무엇인가요?

  • cron 표현식을 이용하여 해당 스케줄러를 얼마나 돌릴지 “주기"를 정할 수 있습니다
  • cron 식은 해당 블로그를 참고하였습니다

 

 

종료됐지만 상태가 AVAILABLE 한 모임 조회

  • querydsl을 이용하여 ZonedDateTime.now()를 기준으로 모임 종료시간이 지났지만 상태가 AVAILABLE한 모임을 조회합니다
public List<Club> findExceedTimeClub() {
        return queryFactory.selectFrom(club)
                           .where(clubStatusEq(ClubStatus.AVAILABLE).and(
                                   club.endDate.after(ZonedDateTime.now())))
                           .fetch();
    }

 

Test

 

Querydsl Test

    @Test
    @DisplayName("모임 종료 시간이 지났는데 현재 상태가 AVAILABLE한 모임을 조회한다")
    void exceedTimeClub() throws Exception {
        List<Club> result = queryFactory.selectFrom(club)
                                       .where(clubStatusEq(ClubStatus.AVAILABLE).and(
                                               club.endDate.after(
                                                       ZonedDateTime.of(2021, 5, 21, 19, 30, 0, 0,
                                                                        ZoneId.of("Asia/Seoul")))))
                                       .fetch();

        assertThat(result.size()).isEqualTo(100);
    }

    private BooleanExpression clubStatusEq(ClubStatus clubStatus) {
        return clubStatus == null ? null : club.status.eq(clubStatus);
    }
  • 더미 데이터에는 AVAILABLE한 모임이 100개가 존재하고, 모임의 종료시간은 설정한 ZonedDateTime을 지났습니다

 

스케줄러 메서드를 실행시킬 경우 모임의 상태가 END로 변경되는지 Test

    @Test
    @DisplayName("스케줄러가 실행될 경우 club의 상태가 END로 변경되어야한다")
    void convertStatusAvailableToEnd() throws Exception {
        //when
        List<Club> savedClubs = clubService.exceedTimeClub();

        //then
        for (Club savedClub : savedClubs) {
            assertThat(savedClub.getStatus()).isEqualTo(ClubStatus.END);
        }
    }

 

728x90

'Spring' 카테고리의 다른 글

Spring @Async  (0) 2023.01.13
HikariCP란 무엇일까?  (0) 2022.10.27
MapStruct  (0) 2022.05.30
spring boot 2.6.x에 swagger 3.0 설정해보자(+수정 openapi 3.0 2022.05.30)  (0) 2022.05.11
Filed Injection을 지양하자!  (0) 2022.05.02
profile

자바생

@자바생

틀린 부분이 있다면 댓글 부탁드립니다~😀

검색 태그