고래씌
[Spring] 12-1. 스케쥴러, Quartz를 이용한 회원 비밀번호 변경 알람(ex. 변경한지 3개월 지난경우 알람) 본문
[Spring] 12-1. 스케쥴러, Quartz를 이용한 회원 비밀번호 변경 알람(ex. 변경한지 3개월 지난경우 알람)
고래씌 2024. 1. 31. 10:251. Spring Scheduler
: 매일, 매분, 매초, 매주, 매달, ... 반복적으로 실행시켜야하는 작업(프로세스)가 있는 경우 스프링 스케쥴러를 사용하면
간편하게 셋팅 가능하다.
<스프링 스케쥴러 작업순서>
1. xml 파일만들고, task, context 스키마를 등록(하단 namespce탭을 이용)
2. 스케쥴링 관련 annotation 활성화
3. 스케쥴러로 사용할 클래스들을 bean 객체로 등록
4. web.xml에 프로그램 구동시 현재 xml에 읽혀지도록 등록 → *-context.xml로 등록했음
5. 스케쥴링을 원하는 메소드에 가서 schedule 어노테이션 추가 → ScheduleController에 추가함
ref : bean 클래스의 변수명 method : 해당 bean클래스의 스케쥴링할 메소드명 cron : * * * * * * * 초 분 시 일 월 요일 년도(생략가능) * : 모든 값(매시 매분 매주 매초) ? : 어떤 값이든 상관없다. - : 범위지정(1-2) 1에서 2초 , : 여러값을 지정. (1,5) 1초랑 5초 / : 증분값. 0/2 → 0초부터 매 2초마다.(증가치 설정가능) L : 지정할 수 있는 범위의 마지막 값 (매달 말일) W : 가장 가까운 "평일"을 설정할 때 # : N번째 특정 요일을 설정할때 매일 30분마다 특정작업을 실행시키고 싶다. 0 30 * * * * 매일 오전 1시에 실행하게 하고 싶다? 0 0 1 * * * * |
▶ scheduler-context.xml
=> context, task 추가
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- #2 -->
<task:annotation-driven scheduler="khScheduler"/>
<!-- #3 -->
<context:component-scan base-package="com.kh.spring.common.scheduling"></context:component-scan>
<task:scheduler id="khScheduler" pool-size="10" />
<!--
pool-size : 쓰레드풀 개수 지정(기본값1)
-->
<task:scheduled-tasks scheduler="khScheduler"> <!-- 관리해야할 작업목록 -->
<task:scheduled ref="scheduleController" method="testCron" cron="1 * * * * *" /> <!-- 1초 간격 -->
</task:scheduled-tasks>
</beans>
▶ ScheduleController.java
package com.kh.spring.common.scheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
public class ScheduleController {
// @Scheduled(fixedDelay = 1000) // 고정시간방식 고정된 시간마다 이 어노테이션이 실행된다.
public void test() {
log.info("1초마다 출력");
}
public void testCron() {
log.info("크론탭 방식 테스트");
}
}
크론메이커에서 cron을 상세하게 편하게 설정할 수 있다!
http://www.cronmaker.com/;jsessionid=node01pgk32hs9k7nq16qzbd9cpa2f81466910.node0?0
CronMaker
www.cronmaker.com
2. Quartz 스케쥴러 - ①
▶ Spring Quartz 설정방법
1. context:coompontentscan 추가 => bean 객체 등록시 필요
2. pom.xml에 Quartz관련된 의존성 3개 추가
Spring quartz에는 작업단위가 크게 3가지 컴포넌트로 나눠져 있음
- Job : 실제로 작업할 작업단위(기능)
- Trigger : Job을 어떤방식으로 실행시킬지 정의
- Scheuler : 내가만든 Trigger들을 등록해서, 내가 원하는 시간에 작업이 이루어지도록 스케쥴링하는 컴포넌트
=> Spring Context Support는 복사후, 해당 스프링 버전으로 재설정
${org.springframework-version}
▶ pom.xml에 붙여놓기
<!-- Spring Quartz 스케쥴러 -->
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.2</version>
</dependency>
<!-- Spring Quartz Job -->
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz-jobs -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.3.2</version>
</dependency>
<!-- Spring Context Support -->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${org.springframework-version}</version>
</dependency>
▶ quartz-context.xml
=> context 추가
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- job 객체 생성(bean 객체 형태)
메소드 단위로 실행되는 스케쥴러(MethodInvokingJobDetailFactoryBean)를 이용해서 객체생서예정
-->
<context:component-scan base-package="com.kh.spring.common.scheduling"></context:component-scan>
<bean id="job1" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="scheduleController"></property>
<property name="targetMethod" value="testQuartz"></property>
<!-- 작업 동시 실행방지 여부 지정 -->
<property name="concurrent" value="false"></property>
</bean>
<!-- Trigger
내가 만든 Job을 통해 동작의 실행방법을 정의
-->
<bean id="jobTrigger1" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean" >
<property name="jobDetail" ref='job1'></property>
<property name="cronExpression" value="0/5 * * 1/1 * ? *"></property>
</bean>
<!--
Scheduler
위에서 정의한 trigger를 관리하고, 정의해둔 트리거를 실행시키는 역할을 하는 객체
-->
<bean id="jobScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!-- 현재 생성된 스케쥴러를 통해 작동시킬 트리거 목록 -->
<property name="triggers">
<!-- list태그로 트리거들 추가 -->
<list>
<ref bean='jobTrigger1' />
</list>
</property>
</bean>
</beans>
▶ ScheduleController.java에 메소드 추가
▶ 결과
3. Quartz 방식 - ② (비밀번호 변경한지 3개월 지났을 때 설정할 예정)
매일 오전 1시에 회원정보를 확인하여, 사용자가 비밀번호를 변경한지 3개월이 지났다면 비밀번호를 변경할 수 있도록 db상태값을 변경해줄 예정
1) db에 changePwd라는 칼럼을 추가
2) 사용자가 비밀번호변경을 안한지 3개월이 넘었다면, changePwd의 상태값을 변경
3) 사용자가 로그인 시도를 할 때 changePwd값이 바꿔져 있다면, 비밀번호 변경페이지로 이동
4) 비밀번호 변경을 하면 changePwd값은 원래 상태값으로 돌아간다.
▶ ChangePwdScheduler.java
package com.kh.spring.common.scheduling;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
import com.kh.spring.member.model.service.MemberService;
@Component
public class ChangePwdScheduler extends QuartzJobBean{
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
// jobdataasmap에서 등록한 빈객체 가져오기
MemberService mService = (MemberService)context.getMergedJobDataMap().get("mService");
mService.updateMemberChangePwd();
}
}
▶ quartz-context.xml
=> job2 추가
=> jobTrigger2 추가
=> jobTrigger2 로 변경
▶ quartz-context.xml 전체코드
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- job 객체 생성(bean 객체 형태)
메소드 단위로 실행되는 스케쥴러(MethodInvokingJobDetailFactoryBean)를 이용해서 객체생서예정
-->
<context:component-scan base-package="com.kh.spring"></context:component-scan>
<bean id="job1" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="scheduleController"></property>
<property name="targetMethod" value="testQuartz"></property>
<!-- 작업 동시 실행방지 여부 지정 -->
<property name="concurrent" value="false"></property>
</bean>
<!-- 비밀번호 변경주기(3개월) 지난경우 알람 -->
<bean id="job2" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<property name="jobClass" value="com.kh.spring.common.scheduling.ChangePwdScheduler"></property>
<property name="jobDataAsMap">
<map>
<!-- class를 가져올 때 첫글자는 소문자로 등록 -->
<entry key="mService" value-ref="memberServiceImpl" />
</map>
</property>
</bean>
<!-- Trigger
내가 만든 Job을 통해 동작의 실행방법을 정의
-->
<bean id="jobTrigger1" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean" >
<property name="jobDetail" ref='job1'></property>
<property name="cronExpression" value="0/5 * * 1/1 * ? *"></property>
</bean>
<!-- 비밀번호 변경주기(3개월) 지난경우 알람 -->
<bean id="jobTrigger2" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean" >
<property name="jobDetail" ref='job2'></property>
<property name="cronExpression" value="0/5 * * 1/1 * ? *"></property>
<!-- <property name="cronExpression" value="0/5 * 1 1/1 * ? *"></property> -->
</bean>
<!--
Scheduler
위에서 정의한 trigger를 관리하고, 정의해둔 트리거를 실행시키는 역할을 하는 객체
-->
<bean id="jobScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!-- 현재 생성된 스케쥴러를 통해 작동시킬 트리거 목록 -->
<property name="triggers">
<!-- list태그로 트리거들 추가 -->
<list>
<!-- 비밀번호 변경주기(3개월) 지난경우 알람 -->
<ref bean='jobTrigger2' />
</list>
</property>
</bean>
</beans>
① SqlDeveloper를 키고 MEMBER테이블에서 CHANGE_PWD 컬럼 추가
② 비밀번호 변경이 3개월이 지났다면 CHANGE_PWD 가 'Y'로 변경되도록 설정
=> 한 회원의 MODIFY_DATE를 비밀변경 변경한지 3개월이 지나도록 위와 같이 변경
▶ MemberService.java
void updateMemberChangePwd();
▶ MemberServiceImpl.java
@Override
public void updateMemberChangePwd() {
memberDao.updateMemberChangePwd();
}
▶ MemberDao.java
void updateMemberChangePwd();
▶ MemberDaoImpl.java
@Override
public void updateMemberChangePwd() {
sqlSession.update("memberMapper.updateMemberChangePwd");
}
▶ member-mapper.xml
<!-- 비밀번호 변경(3개월) 지났다면 'Y'로 변경 -->
<update id="updateMemberChangePwd">
UPDATE MEMBER
SET CHANGE_PWD = 'Y'
WHERE SYSDATE > ADD_MONTHS(MODIFY_DATE, 3)
</update>
=> DB에 CHANGE_PWD가 자동으로 'Y'로 바뀌는 것을 확인할 수 있다!
▶ 회원가입 쪽 member-mapper.xml 수정
=> 새로운 칼럼 추가되었으므로 DEFAULT 추가 (CHANGE_PWD = 'N' 기본값이 들어가도록)
=> CHANGE_PWD = 'N' 추가
▶ Member.java 칼럼에도 changePwd 추가
▶ MemberController.java
=> 사용자의 비밀번호 변경여부 확인을 위해 아래 코드 추가
▶ 결과
해당 아이디로 로그인한 결과, 이와 같은 알람창이 정상적으로 뜨는 것을 확인할 수 있다.
'Server > Spring' 카테고리의 다른 글
[Spring] 13. Aop (0) | 2024.01.31 |
---|---|
[Spring] 12-2. DB에는 존재하지 않는 파일인데 images 안에만 존재하는 파일 삭제하는 스케쥴러 (0) | 2024.01.31 |
[Spring] 11-3. 로그인 여부 체크하는 인터셉터 (0) | 2024.01.30 |
[Spring] 11-2. 인터셉터 이용해서 로깅 처리 (0) | 2024.01.30 |
[Spring] 11-1. 로그 처리 (0) | 2024.01.30 |