-
[Spring] 스케줄러 만들어보기웹 개발/Spring Framework 2018. 12. 18. 16:22
스케줄링.md xml에서 스프링 스케줄링 구현하기(xml task 네임스페이스 활용)
구글링을 해봤을 때, java단에서 스케줄링을 구현하는 경우가 많았다. xml에서 구현하는 법은 잘 안보여서 정리해둬야짓.
스프링은 서비스 추상화 기법을 이용해서 스케줄링 기술에 독립적인 사용이 가능한 추상화 서비스 인터페이스인 TaskScheduler를 제공한다. TaskScheduler는 조건에 따라 실행하거나 반복적인 작업을 수행한다.
주어진 태스크는 특정 시간에 동작하거나 일정 간격으로 실행되게 만들수 있다. 그 중 task 네임스페이스를 활용해서 스케줄러 만드는 법을 소개해보려한다.
먼저 스케줄러가 들어갈 xml에서 TaskScheduler 타입의 ThreadPoolTaskScheduler 빈을 등록한다. spring doc를 참조하면, ThreadPoolTaskScheduler는 TaskScheduler 인터페이스의 구현체이다. id와 pool-size를 지정할 수 있는데, pool-size의 default는 1이다.
<task:scheduler id="autoMemberScheduler" pool-size="5"/>
등록했으면, 스케줄러를 이용해 어떤 task를 수행할지 java단에서 구현해준다.
@Component("membershipTask") public class MembershipTask { private Logger logger = Logger.getLogger(this.getClass()); @Autowired private MembershipTaskService membershipTaskService; @Async public void updateLatestMember() { try{ logger.debug("Scheduler updateLatestMember start"); membershipTaskService.updateLatestMember(); logger.debug("Scheduler updateLatestMember end"); }catch (Exception e) { logger.error(">>>>>>>>최신 회원으로 업데이트 중 에러 발생", e); } } }
@Component로 스케줄러에 사용될 클래스를 빈으로 등록해준다. 다음 스케줄러 발생 시 실행할 메서드(예시에서 updateLatestMember 메서드)를 만들어준다. @Async는 부여된 메서드를 자동으로 비동기 방식으로 실행시킨다. 비동기로 동작해서 메서드 작업 시간이 소요되더라도 바로 리턴되고, 메서드는 별도의 스레드로 동작한다. 이때 메서드의 리턴 타입은 void 또는 Future 타입이어야 하고, 메서드는 파라미터를 가질 수 있다.
task 메서드 작성이 끝났으면, 다시 스케줄러가 들어갈 xml로 돌아와서 아래의 코드를 추가해준다.
<task:scheduled-tasks scheduler="autoMemberScheduler"> <task:scheduled ref="membershipTask" method="updateLatestMember" cron="0 0 0 1 * *"/> </task:scheduled-tasks>
task:scheduled-tasks에서 scheduler에는 위에서 등록한 scheduler id를 작성하고, task:scheduled에서 ref는 등록한 빈 아이디를 입력한다. method에는 task가 실행될 메서드 명을 입력하면 된다. 실행시간 포맷은 cron을 활용한다. cron은 유닉스 계열 OS에서 시간기반의 잡 스케줄러이다.
cron 포맷은 다음과 같다. <초> <분> <시간> <일> <월> <요일> <년도>
여기서 년도는 선택사항이다.예시)
- 매달 1일 0시 0분 0초에 실행 - cron= " 0 0 0 1 * * "
- 5초 간격으로 실행 - cron= " */5 * * * * * "
여기까지 작성했다면 콘솔에 찍히는 걸 확인하면 끝~!
참조: 토비의 스프링 3.1(에이콘 출판사)
'웹 개발 > Spring Framework' 카테고리의 다른 글
[Spring]필드 주입(Field Injection) 대신 생성자 주입(Constructor Injection)을 사용해야 하는 이유 (2) 2018.12.31 [Spring] e.printStackTrace() vs logger.error(logger.error를 사용해야하는 이유) (0) 2018.12.22 [Mybatis]mybatis에서 테이블의 언더바 컬럼을 카멜형식으로 변환해주는 설정 (0) 2018.11.20 [Spring] @PostConstruct란?(정의와 장점) (0) 2018.11.12 @Transactional(선언적 트랜잭션) bean Id 지정해서 사용하기 (0) 2018.06.28