스프링 스케쥴러 : 스프링이 알아서 때에 맞춰 코드 수행해 줌

-> 코드를 수행하려면 해당 클래스가 객체 형대로 존재해야함

-> Bean 필요 -> @Component

 

@Scheduled : Spring 에서 제공하는 스케쥴러 : 시간에 따른 특정 잡업의 순서를 지정하는 방법

 

설정방법 

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

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

 

@Scheduled 속성

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

  -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 : 마지막. (월, 요일만 해당)

 

* 주의사항 - @Scheduled 어노테이션은 매개변수가 없는 메소드에만 적용 가능.

 

@Scheduled(fixedDelay = 3000) : 3초마다

@Scheduled(cron = "0 * * * * *")//모든 년월일시분, 요일 0 초 마다: 매분 0초마다 라는 뜻(매분마다) 

@Scheduled(cron ="( 0 0 * * .. == 0분 0초 == 정시 마다) 

@Scheduled(cron ="( 0 0 0 * .. == 0시 0분 0초 == 자정 마다)

 

 

// +스케쥴러를 이용한 가비지 파일 삭제

String serverPath = servletContext.getRealPath("/resources/images/board");
		//이미지가 저장되어있는 실제 경로
		//위에서 DI로 ServletConetx를 받아놓는다
        
		File[] imgArr = new File(serverPath).listFiles();
		//지정된 경로에 있는 모든 파일 리스트를 File배열로 반환
		//File객체 : 파일을 참조할 수 있는 객체
		
		//배열을 리스트로 변환
		List<File> serverImgList = Arrays.asList(imgArr);
		
		//이미지가 저장된 폴더에 있는 파일 목록을 잘 가져왔는지 확인
		/*
		 * for(File img : serverImgList) { System.out.println(img); }
		 */
		
		//DB에서 파일명 목록 조회
		List<String> dbImgList = boardService.selectImgList();
		System.out.println(dbImgList);
		//serverImgList : 서버에 저장된 파일 목록
		//dbImgList : DB에 저장된 파일명 목록
		
		//서버 DB 모두 비어있지 않은 경우
		if(!serverImgList.isEmpty() &&!dbImgList.isEmpty() ) {
			for(File img : serverImgList) {
				
				String serverImgName = 
						img.toString().substring(img.toString().lastIndexOf("\\")+1);
					
						//img.toString : 경로 + 파일명
						//.substring -> 문자열 시작부터 지정된 index 이전까지 문자열을 모두 삭제
				if(dbImgList.indexOf(serverImgName) == -1) {
					//DB파일명 목록에 서버 파일명과 같은 이름이 없다면
					System.out.println(serverImgName+"삭제");
					img.delete();
				}
			}
		}

 

스프링의 핵심 가치 = 객체지향 프로그래밍이다

그런다면 좋은 객체지향 프로그래밍이란?
--객체를 설계할 떄 역할과 구현을 명확히 분리해야 함--

==  구현을 뭐로 바꾸든 역할은 변함없어야한다 ==
1) SRP : 단일책임원칙
-한 클래스는 하나의 책임만 가져야한다
2) OCP : 개방-폐쇄 원칙 
- 소프트웨어 요소는 확장에는 열려있으나 변경에는 닫혀있어야 한다 (다형성 의미)
3) LSP 리스코프 치환 원칙 : 

-프로그램의 객체는 정확성을 깨지 않으면서 하위 타입 인스턴스로 바꿀 수 있어야한다
4) ISP 인터페이스 분리 원칙 : 

-인터페이스 여러개가 범용 한개보다 낫다
5) DIP 의존관계 역전 원칙 : 

-추상화에 의존해야지 구체화에 의존하면 안된다 ( 인터페이스에 의존해라)

 

이를 위해 다형성이 중요하다! 하지만 다형성 만으로는 쉽게 갈아끼우듯 사용이 어려움 -> 스프링의 탄생

 

EX) 인터페이스1 = new 구현체 1

이라는 구문에서 구현체 1이 구현체 2로 바뀐다면?

---->정의하는 new 코드를 바꿔주어야한다

 

결국 해당 클래스는 인터페이스를 사용하며 DIP를 준수해서 추상화에 의존한것처럼 보였지만 

사실 인터페이스와 구현체 둘 전부에 의존해있는 상태인 것이다

-> 이러한 문제를 해결하기 위해 생성자 안에 무엇을 전달받던 그냥 받기만 하는 상태로 만들어

자신의 역할에만 집중할 수 있도록 해주고

누군가가 생성의 역할을 해줘야 좋은 설계이다. 그리고 이것이 스프링의 원리가 된다!

 

 

1. 모듈 설정

 

1-1) 메이븐 레포지토리 -> spring security 검색

-Spring Security Core 

-Spring Security Config

두 가지를 사용하며 pom.xml에 추가

 

=====properties : 메이븐이 적용된 프로젝트에서 공통적으로 
사용할 버전 또는 설정값 정보를 작성하는 태그=========
<properties>
<java-version>1.8</java-version>
<org.springframework-version>5.2.10.RELEASE</org.springframework-version>
<org.aspectj-version>1.9.4</org.aspectj-version>
<org.slf4j-version>1.7.25</org.slf4j-version>
</properties>

 

별 이슈없으면 properties로 적용해놓은것과 일치하도록  모듈 버젼에도 ${org.springframework-version} 입력한다.

 

----메이븐에서 설정 문제가 자주 나므로 혹시 모르니 추가----

         <!-- 메이븐 구성 문제로 인한 pom.xml 문제 해결 -->
         <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <version>3.2.2</version>
         </plugin>

 

 

1-2) pom.xml 추가 후 설정 관련 resource 폴더에 spring-security.xml 생성

 

---생성 후 namespace 탭에서 security 체크한다

---beans 내부에 작성한다

<bean id="bCryptPasswordEncoder"
class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" />

(BCrypt클래스의 경로이다)

 

1-3) web.xml로 이동해서 구문을 추가한다

<context-param> 에 <param-value>안에 classpath:spring/appServlet/spring-security.xml

 

서버가 시작하면 web.xml 제일먼저 -> 그중 param-value 읽어들임

-> spring-security를 등록했으므로 그 안의 bean 읽어 스프링이 객체 관리 -> DI 사용 가능해짐

 

 

2. 사용

2-1 객체 DI

@Autowired
private BCryptPasswordEncoder encoder;
//Bean으로 등록된 BCryptPasswordEncoder 객체를 의존성 주입(DI)

 

2-2 암호화 진행

encoder.encode(문자열) => 암호화 문자열 반환

encoder.matches(원본 문자열 , 암호화 된 문자열 ) => 원본과 암호화문자가 일치하는지 true / false

 

 

SHA-512는 매번 같은 암호화 문자열이 반환되는 문자가 생성되는 문제가 있는데 반해

Bcrypt 암호화는 매번 다른 문자열이 반환되고 확인해낼 수 있다

 

+ Recent posts