[팀 프로젝트 (운동루틴관리앱)] 스케줄링

스케줄링 어노테이션 간략 설명
화낼거양's avatar
Feb 28, 2025
[팀 프로젝트 (운동루틴관리앱)] 스케줄링
 
 
💡
스케줄링은 특정 작업이나 프로세스를 미리 정해진 시간이나 간격에 따라 자동으로 실행하는 것을 의미합니다. 이를 통해 반복적인 작업을 자동화할 수 있어 사용자가 수동으로 실행하지 않아도 됩니다. 주로 시스템 관리, 데이터 백업, 로그 파일 정리, 보고서 생성 등의 작업을 자동화하는 데 사용됩니다.
 
 
 
@EnableScheduling // 스케줄링 기능 활성화 public class RecodeService {
 
  • 스케줄링을 사용하기 위해서는 클래스 위에 @EnableScheduling 어노테이션을 붙여야 합니다.
  • 해당 어노테이션은 스케줄링을 활성화합니다.
 
 
 
@Scheduled(cron = "0 0 1 * * MON") // 매주 월요일 오전 1시에 실행 public void updateAllUserPlan() {
 
  • 특정시간에 실행시키고 싶은 메서드 위에 @Scheduled 어노테이션을 작성합니다.
  • 어노테이션 다음의 (cron = "0 0 1 * * MON") 예시는 매주 월요일 오전 1시에 실행하겠다는 의미입니다. 값을 변경하여 자신이 원하는 시간에 해당 메서드 아래의 내용을 실행시킬 수 있습니다.
 
 

참고사항 :

 
@Scheduled(cron = "0 0 1 * * MON") 는 다음과 같이 해석할 수 있습니다:
  • 첫 번째 0은 초 단위입니다. 여기서는 0초를 의미합니다.
  • 두 번째 0은 분 단위입니다. 여기서는 0분을 의미합니다.
  • 세 번째 1은 시간 단위입니다. 여기서는 오전 1시를 의미합니다.
  • 네 번째 은 일 단위입니다. 여기서는 매일을 의미합니다.
  • 다섯 번째 은 월 단위입니다. 여기서는 매달을 의미합니다.
  • 여섯 번째 MON은 요일 단위입니다. 여기서는 월요일을 의미합니다.
 
 
  • 스케줄링을 실적용한 코드 전체 내용
클릭시 전체 코드를 확인할 수 있습니다.
package com.metacoding.exerciseappserver.recode; import com.metacoding.exerciseappserver._core.util.CommonData; import com.metacoding.exerciseappserver.plan.Plan; import com.metacoding.exerciseappserver.plan.PlanRepository; import com.metacoding.exerciseappserver.user.UserRepository; import lombok.RequiredArgsConstructor; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDateTime; import java.util.*; @Transactional(readOnly = true) @RequiredArgsConstructor @Service @EnableScheduling // 스케줄링 기능 활성화 public class RecodeService { private final RecodeRepository recodeRepository; private final PlanRepository planRepository; private final UserRepository userRepository; public RecodeRequest.RecodeDTO findAllRecodeByUserId(Integer userId) { List<Recode> recodeList = recodeRepository.findAllRecodeByUserId(userId); List<RecodeRequest.RecodeInformation> list = new ArrayList<>(); for (Recode recode : recodeList) { list.add(new RecodeRequest.RecodeInformation(recode)); } return new RecodeRequest.RecodeDTO(list); } @Transactional @Scheduled(cron = "0 0 1 * * MON") // 매주 월요일 오전 1시에 실행 public void updateAllUserPlan() { // 모든 Plan을 유저 아이디 기준으로 오름차순 정렬하여 가져오기 List<Plan> planList = planRepository.findAllPlan(); Set<Integer> userIdSet = new HashSet<>(); for (Plan plan : planList) { userIdSet.add(plan.getUser().getId()); } List<Integer> userIdList = new ArrayList<>(userIdSet); for (int userId : userIdList) { int count = 0; LocalDateTime baseCreatedAt = LocalDateTime.now(); // 기본 날짜 설정 while (count < 7) { boolean found = false; for (Plan plan : planList) { if (plan.getUser().getId() == userId && plan.getDayOfWeek().equals(CommonData.weekNameArr[count])) { boolean isChecked = plan.getFitnessCheckStatus(); LocalDateTime createdAt = baseCreatedAt.minusDays(7 - count); // 날짜를 유동적으로 조정 recodeRepository.save(Recode.builder() .user(userRepository.findById(userId).orElseThrow(() -> new IllegalArgumentException("Invalid user ID"))) .createdAt(createdAt) .isChecked(isChecked) .build()); count++; found = true; break; // 내부 루프 탈출 } } if (!found) { count++; // 찾지 못한 경우에도 count 증가 } } } // 모든 Plan을 초기화 for (Plan plan : planList) { plan.updatePlan(null, null, null, false); } } }
 
Share article

moohyun