@EnableScheduling
@EnableScheduling // background task executer가 생성된다.
@SpringBootApplication
public class OnlineshopApplication {
public static void main(String[] args) {
SpringApplication.run(OnlineshopApplication.class, args);
}
}
@Scheduled
cron : cron 표현식을 지원. ‘초 분 시 일 월 주 (년)’ 으로 표현
fixedDelay : ms 단위. 이전 작업이 끝난 시점부터 고정된 호출 간격을 설정.
fixedRate : ms 단위. 이전 작업이 수행되기 시작한 시점부터 고정된 호출 간격 설정.
initialDelay : 초기 지연 시간.(스케줄러에서 메서드가 등록되자마자 수행하지 않고 설정해준 시간 후부터 동작)
zone : cron 표현식을 사용할 때 적용할 time zone. 따로 지정하지 않으면 서버의 time zone
/**
* 주기적으로 모든 고객의 멤버십을 업데이트하는 메서드.
* 월요일 새벽 4시에 실행됩니다.
*/
@Transactional
@Scheduled(cron = "0 0 4 ? * MON")
public void updateAllMemberShip() {
// 모든 고객 정보를 조회합니다.
List<Customer> customers = customerRepository.findAll();
// 각 고객에 대해 멤버십을 업데이트합니다.
for (Customer customer : customers) {
updateMembershipForCustomer(customer);
}
}
/**
* 특정 고객의 멤버십을 업데이트하는 메서드.
*
* @param customer 업데이트할 고객
*/
private void updateMembershipForCustomer(Customer customer) {
// 고객의 총 구매액을 조회합니다.
BigDecimal totalPurchaseAmount = customer.getTotalPurchaseAmount();
// 현재 총 구매액에 따라 업그레이드 가능한 멤버십을 조회합니다.
memberShipRepository.findNextMemberShip(totalPurchaseAmount)
.stream()
.findFirst()
.filter(memberShip -> totalPurchaseAmount.compareTo(memberShip.getBaseline()) > 0)
.ifPresent(memberShip -> {
// 멤버십 업데이트를 로그에 기록합니다.
log.info("{} 회원이 {}로 업데이트 되었습니다.", customer.getId(), memberShip.getLevel());
// 실제 멤버십을 업데이트합니다.
customer.upgradeMemberShip(memberShip);
});
}