Spring Scheduler (23.09.01)

·2023년 9월 1일
0

Spring

목록 보기
29/36
post-thumbnail

🌷 Spring Scheduler

스프링에서 제공하는 스케쥴러
@Scheduled 어노테이션 사용

  • 스케쥴러 : 시간에 따른 특정 작업(Job)의 순서를 지정하는 방법

🌼 설정 방법

1) servlet-context.xml ▶ Namespaces 탭 ▶ task 체크 후 저장

2) servlet-context.xml ▶ Source 탭 ▶ <task:annotation-driven/> 추가

🔎 servlet-context.xml

...
	<!-- namespaces 탭에서 aop, tx 체크 -->
	
	<!-- 스프링 스케쥴러 어노테이션 인식 -->
	<task:annotation-driven/>
...

🌼 @Scheduled 속성

@Scheduled 어노테이션은 매개변수가 없는 메소드에만 적용 가능하다.

🌱 fixedDelay

이전 작업이 끝난 시점으로 부터 고정된 시간(ms)을 설정

@Scheduled(fixedDelay  = 10000)
// 이전 작업이 끝난 후 10초 뒤에 실행

🌱 fixedRate

이전 작업이 수행되기 시작한 시점으로 부터 고정된 시간(ms)을 설정.

@Scheduled(fixedRate = 10000)
// 이전 작업이 시작된 후 10초 뒤에 실행

🌱 cron 속성

UNIX 계열 잡 스케쥴러 표현식으로 작성

🔎 작성 방법

cron="초 분 시 일 월 요일 [년도]" - 요일 : 1(SUN) ~ 7(SAT)
  • * : 모든 수
  • - : 두 수 사이의 값. ex) 10-15 -> 10이상 15이하
  • , : 특정 값 지정. ex) 3,4,7 -> 3,4,7 지정
  • / : 값의 증가. ex) 0/5 -> 0부터 시작하여 5마다
  • ? : 특별한 값이 없음. (월, 요일만 해당)
  • L : 마지막. (월, 요일만 해당)

🔎 예시

2019년 9월 16일 월요일 10시 30분 20초
cron="20 30 10 16 9 2 " // 연도 생략 가능

@Scheduled(cron="0 * * * * *") // 매 분마다 실행

이 스케쥴러 기능을 활용하여 서버에 있는 이미지명과 DB에 저장된 이미지명이 다를 경우 서버에서 해당 이미지를 삭제하는 기능을 구현해 볼 것이다.

🌷 DB 이미지(파일) 목록 조회

👀 코드로 살펴보기

🌱 ImageDeleteScheduling.java

package edu.kh.project.common.scheduling;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.servlet.ServletContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import edu.kh.project.board.model.service.BoardService;

// 스프링이 일정 시간마다 해당 객체를 이용해서 코드를 수행
// == 스프링이 해당 클래스를 객체로 만들어서 관리를 해야 된다.
// == Bean 등록

@Component // @Controller, @Service, @Repository의 부모 어노테이션
		   // Bean 등록을 하겠다고 명시하는 어노테이션
public class ImageDeleteScheduling {
	
	@Autowired
	private ServletContext servletContext;
	
	@Autowired
	private BoardService service;
	
	//@Scheduled(fixedDelay = 10000) // ms 단위
	// 5초 동안 작업 -> 10초 대기 -> 작업(5초) -> 10초 대기
	
	//@Scheduled(fixedRate = 10000)
	// 일(5초)
	// 대기(10초)
	
	// cron="초 분 시 일 월 요일 [년도]"
	//@Scheduled(cron = "0,30 * * * * *")
	@Scheduled(cron = "0 0 * * * *") // 매 정시(*시 0분 0초)
	public void test() {
		// System.out.println("스케쥴러가 일정 시간마다 자동으로 출력");
		
		System.out.println("----------- 게시판 DB, 서버 불일치 파일 제거 -----------");
		
		// 서버에 저장된 파일 목록을 조회해서
		// DB에 저장된 파일 목록과 비교하여
		// 매칭되지 않는 서버 파일 제거
		
		// 1) 서버에 저장된 파일 목록 조회
		// -> application 객체를 이용해서
		//	  /resources/images/board의 실제 서버 경로를 얻어옴
		String filePath = servletContext.getRealPath("/resources/images/board");
		// C:\workspace\6_Framework\boardProject\src\main\webapp\resources\images\board
		
		// 2) filePath에 저장된 모든 파일 목록 읽어오기
		File path = new File(filePath);
		File[] imageArr = path.listFiles();
		
		// 배열 -> List로 변환
		List<File> serverImageList = Arrays.asList(imageArr);
		
		// 확인 (임시)
//		for(File f : serverImageList) {
//			System.out.println(f.toString());
//		}

		// 3) DB 파일 목록 조회
		List<String> dbImageList = service.selectImageList();
		
		// 확인 (임시)
//		for(String s : dbImageList) {
//			System.out.println(s);
//		}
		
		// 4) 서버에 파일 목록이 있을 경우에 비교
		if(!serverImageList.isEmpty()) {
			
			// 5) 서버 파일 목록 순차 접근
			for(File server : serverImageList) {
				
				// 6) 서버에 존재하는 파일이
				//	  DB(dbImageList)에 없다면 삭제
				// String[] temp = server.toString().split("\\");
				// String s = temp[temp.length-1];
				
				// System.out.println(server.getName());
				
				// List.indexOf(객체) = 객체가 List에 있으면 해당 인덱스 반환
				//					   없으면 -1 반환
				if(dbImageList.indexOf(server.getName()) == -1) {
				// db 파일 목록			서버 파일 이름
					
					System.out.println(server.getName() + "삭제");
					server.delete(); // File.delete() : 파일 삭제
				}
			} // for문 종료
			System.out.println("----------- 이미지 파일 삭제 스케쥴러 종료 -----------");
		}
	}
}

🌱 boardService.java

...
	/** DB 이미지(파일) 목록 조회
	 * @return list
	 */
	List<String> selectImageList();

🌱 boardServiceImpl.java

...
	// DB 이미지(파일) 목록 조회
	@Override
	public List<String> selectImageList() {
		return dao.selectImageList();
	}

🌱 boardDAO.java

...
	/** DB 이미지(파일) 목록 조회
	 * @return list
	 */
	public List<String> selectImageList() {
		return sqlSession.selectList("boardMapper.selectImageListAll");
	}

🌱 boardMapper.xml

...
	<!-- DB 이미지(파일) 목록 조회 -->
	<select id="selectImageListAll" resultType="string">
		SELECT IMG_RENAME FROM BOARD_IMG
	</select>

코드를 작성한 뒤 서버를 실행하면 지정한 시간마다 이미지 목록을 조회하고 비교하여 이미지명이 일치하지 않는 이미지를 삭제해 준다.

profile
풀스택 개발자 기록집 📁

0개의 댓글