[SPRING] Quartz 트리거를 데이터베이스에 유지하는 올바른 방법
SPRINGQuartz 트리거를 데이터베이스에 유지하는 올바른 방법
저는 Quartz를 처음 접했고 Spring 웹 애플리케이션에서 일부 작업을 스케줄해야합니다.
저는 Spring + Quartz 통합에 대해 알고 있습니다. (Spring v 3.1.1을 사용하고 있습니다.) 이것이 올바른 방법인지 궁금합니다.
특히 응용 프로그램을 다시 시작할 때 다시 초기화 할 수 있도록 예약 된 작업을 DB에 유지해야합니다.
Spring 스케쥴링 래퍼가 제공하는 유틸리티가 있습니까? 따라야 할 "잘 알려진"접근 방식을 제안 해 주시겠습니까?
해결법
-
==============================
1.이 시나리오를 처리하는 한 가지 방법이 있습니다.
이 시나리오를 처리하는 한 가지 방법이 있습니다.
먼저 Spring Configuration에서 SchedulerFactoryBean을 지정하여 다른 Bean에 Scheduler를 삽입 할 수 있습니다.
<bean name="SchedulerFactory" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="applicationContextSchedulerContextKey"> <value>applicationContext</value> </property> </bean>
그런 다음 응용 프로그램에서 작업을 만들 때 작업의 세부 정보를 데이터베이스에 저장합니다. 이 서비스는 내 컨트롤러 중 하나에 의해 호출되며 작업을 예약합니다.
@Component public class FollowJobService { @Autowired private FollowJobRepository followJobRepository; @Autowired Scheduler scheduler; @Autowired ListableBeanFactory beanFactory; @Autowired JobSchedulerLocator locator; public FollowJob findByClient(Client client){ return followJobRepository.findByClient(client); } public void saveAndSchedule(FollowJob job) { job.setJobType(JobType.FOLLOW_JOB); job.setCreatedDt(new Date()); job.setIsEnabled(true); job.setIsCompleted(false); JobContext context = new JobContext(beanFactory, scheduler, locator, job); job.setQuartzGroup(context.getQuartzGroup()); job.setQuartzName(context.getQuartzName()); followJobRepository.save(job); JobSchedulerUtil.schedule(new JobContext(beanFactory, scheduler, locator, job)); } }
빌드 한 JobContext에는 작업에 대한 세부 정보가 포함되어 있으며 결국 작업 예약을위한 유틸리티로 전달됩니다. 다음은 작업을 실제로 스케쥴하는 유틸리티 메소드의 코드입니다. 내 서비스에서 JobScheduler를 autowire하고 JobContext에 전달합니다. 또한 저장소를 사용하여 데이터베이스에 작업을 저장합니다.
/** * Schedules a DATA_MINING_JOB for the client. The job will attempt to enter * followers of the target into the database. */ @Override public void schedule(JobContext context) { Client client = context.getNetworkSociallyJob().getClient(); this.logScheduleAttempt(context, client); JobDetail jobDetails = JobBuilder.newJob(this.getJobClass()).withIdentity(context.getQuartzName(), context.getQuartzGroup()).build(); jobDetails.getJobDataMap().put("job", context.getNetworkSociallyJob()); jobDetails.getJobDataMap().put("repositories", context.getRepositories()); Trigger trigger = TriggerBuilder.newTrigger().withIdentity(context.getQuartzName() + "-trigger", context.getQuartzGroup()) .withSchedule(cronSchedule(this.getSchedule())).build(); try { context.getScheduler().scheduleJob(jobDetails, trigger); this.logSuccess(context, client); } catch (SchedulerException e) { this.logFailure(context, client); e.printStackTrace(); } }
따라서이 코드가 모두 실행 된 후에 두 가지 일이 발생했습니다. 내 작업은 데이터베이스에 저장되며 쿼츠 스케줄러를 사용하여 예약되었습니다. 이제 응용 프로그램이 다시 시작되면 스케줄러로 작업을 다시 예약하려고합니다. 이를 위해 컨테이너가 다시 시작되거나 시작될 때마다 Spring에 의해 호출되는 ApplicationListener
를 구현하는 bean을 등록합니다. <bean id="jobInitializer" class="com.network.socially.web.jobs.JobInitializer"/>
JobInitializer.class
public class JobInitializer implements ApplicationListener<ContextRefreshedEvent> { Logger logger = LoggerFactory.getLogger(JobInitializer.class); @Autowired DataMiningJobRepository repository; @Autowired ApplicationJobRepository jobRepository; @Autowired Scheduler scheduler; @Autowired JobSchedulerLocator locator; @Autowired ListableBeanFactory beanFactory; @Override public void onApplicationEvent(ContextRefreshedEvent event) { logger.info("Job Initilizer started."); //TODO: Modify this call to only pull completed & enabled jobs for (ApplicationJob applicationJob : jobRepository.findAll()) { if (applicationJob.getIsEnabled() && (applicationJob.getIsCompleted() == null || !applicationJob.getIsCompleted())) { JobSchedulerUtil.schedule(new JobContext(beanFactory, scheduler, locator, applicationJob)); } } } }
이 클래스는 ApplicationJob 인터페이스를 구현하는 각 작업의 인스턴스를 잡는 스케줄러와 저장소를 autowires합니다. 이러한 데이터베이스 레코드의 정보를 사용하여 스케줄러 유틸리티를 사용하여 작업을 재구성 할 수 있습니다.
그래서 기본적으로 수동으로 데이터베이스에 작업을 저장하고 스케줄러의 인스턴스를 적절한 bean에 삽입하여 수동으로 스케줄링합니다. 다시 일정을 잡으려면 데이터베이스에 쿼리 한 다음 ApplicationListener를 사용하여 컨테이너의 다시 시작 및 시작을 고려하여 일정을 예약합니다.
-
==============================
2.Spring과 Quartz JDBC 작업 저장소 통합에 사용할 수있는 문서가 꽤 있다고 가정합니다. 예를 들면 :
Spring과 Quartz JDBC 작업 저장소 통합에 사용할 수있는 문서가 꽤 있다고 가정합니다. 예를 들면 :
from https://stackoverflow.com/questions/17402112/correct-way-to-persist-quartz-triggers-in-database by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 안드로이드에서 스프링과 같은 패키지 스캐닝 구현하기 (0) | 2019.03.17 |
---|---|
[SPRING] EclipseLink 2.0 및 Spring 3.0.5 및 Tomcat 6을 구성하는 방법은 무엇입니까? (0) | 2019.03.17 |
[SPRING] 사용자 당 하나의 세션 만 허용 (0) | 2019.03.17 |
[SPRING] Spring OpenSessionInViewInterceptor가 작동하지 않습니다. (0) | 2019.03.17 |
[SPRING] 요청 사이에 스프링이있는 상태 유지 (0) | 2019.03.17 |