๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
BackEnd/Spring

[Spring] Quartz ์Šค์ผ€์ค„๋Ÿฌ ๋“ฑ๋ก/ SchedulerFactoryBean

by DEV_SE 2024. 9. 3.

 

๐Ÿš€ SchedulerFactoryBean ํด๋ž˜์Šค๋ฅผ ํ†ตํ•œ Quartz Scheduler ๋“ฑ๋ก

 

๐Ÿš€ SchedulerFactoryBean ์ด๋ž€?

Quartz org.quartz.Scheduler, ๋ฅผ ์ƒ์„ฑ ๋ฐ ์„ค์ •ํ•˜๊ณ , ์Šคํ”„๋ง ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…์ŠคํŠธ์˜ ์ผ๋ถ€๋กœ ๋ผ์ดํ”„์‚ฌ์ดํด์„ ๊ด€๋ฆฌํ•˜๋ฉฐ, ์ข…์†์„ฑ ์ฃผ์ž…์„ ์œ„ํ•œ ๋นˆ ์ฐธ์กฐ๋กœ ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ๋…ธ์ถœํ•˜๋Š” FactoryBean. ์ž‘์—… ์„ธ๋ถ€ ์ •๋ณด, ์บ˜๋ฆฐ๋” ๋ฐ ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ดˆ๊ธฐํ™” ์‹œ ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ์ž๋™์œผ๋กœ ์‹œ์ž‘ํ•˜๊ณ  ํŒŒ๊ดด ์‹œ ์ข…๋ฃŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

> ์ฆ‰, ์ƒ์„ฑ ํ•˜๋ฉด ์Šคํ”„๋ง์ด ์•Œ์•„์„œ ๊ด€๋ฆฌํ•ด์ค€๋‹ค! 

"์Šคํ”„๋ง์˜ IoC ์ปจํ…Œ์ด๋„ˆ์— ์˜ํ•ด ๋นˆ์œผ๋กœ ์ƒ์„ฑ๋˜๋ฉด, ์Šคํ”„๋ง์ด ํ•ด๋‹น ๋นˆ์˜ ๋ผ์ดํ”„์‚ฌ์ดํด์„ ๊ด€๋ฆฌํ•˜๋ฏ€๋กœ ๊ฐœ๋ฐœ์ž๋Š” ์Šค์ผ€์ค„๋Ÿฌ์˜ ์ƒ์„ฑ, ์ดˆ๊ธฐํ™”, ์‹œ์ž‘, ์ข…๋ฃŒ ๋“ฑ์˜ ์ž‘์—…์„ ์ˆ˜๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค."

๋”๋ณด๊ธฐ

IoC ์ปจํ…Œ์ด๋„ˆ์˜ ์ข…๋ฅ˜

์Šคํ”„๋ง์—์„œ๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ IoC ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, ์ผ๋ฐ˜์ ์œผ๋กœ ApplicationContext ๋ฅผ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ

IoC ์ปจํ…Œ์ด๋„ˆ์„ค๋ช…

 

BeanFactory ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ IoC ์ปจํ…Œ์ด๋„ˆ๋กœ, ์ง€์—ฐ ์ดˆ๊ธฐํ™”(lazy loading) ๋ฐฉ์‹์œผ๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•จ.
ApplicationContext BeanFactory๋ฅผ ํ™•์žฅํ•œ ์ปจํ…Œ์ด๋„ˆ๋กœ, ๋ถ€๊ฐ€์ ์ธ ๊ธฐ๋Šฅ (AOP, ํŠธ๋žœ์žญ์…˜, ๋ฉ”์‹œ์ง€์†Œ์Šค ๋“ฑ) ์„ ์ง€์›ํ•จ.
WebApplicationContext ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉ๋˜๋Š” IoC ์ปจํ…Œ์ด๋„ˆ.

 

 

๐Ÿ”น SchedulerFactoryBean๊ณผ IoC ์ปจํ…Œ์ด๋„ˆ์˜ ๊ด€๊ณ„

๐Ÿ’ก SchedulerFactoryBean์€ ApplicationContext์— ์˜ํ•ด ๊ด€๋ฆฌ๋˜๋Š” ํ•˜๋‚˜์˜ ๋นˆ(Bean) ์ž…๋‹ˆ๋‹ค.
์ฆ‰, ์Šคํ”„๋ง IoC ์ปจํ…Œ์ด๋„ˆ๊ฐ€ SchedulerFactoryBean์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ์ž๋™์œผ๋กœ ๊ด€๋ฆฌํ•˜๋ฏ€๋กœ, ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ Scheduler ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ข…๋ฃŒํ•  ํ•„์š” ์—†์ด ์Šคํ”„๋ง์ด ์•Œ์•„์„œ ์ƒ์„ฑํ•˜๊ณ  ์†Œ๋ฉธ์‹œ์ผœ ์ค๋‹ˆ๋‹ค.

 

 

์Šค์ผ€์ค„๋Ÿฌ ์„ค์ •, Quartz ํŠธ๋ฆฌ๊ฑฐ ์„ค์ • ๋ถ€๋ถ„์„ ๊ธฐ๋ก ํ–ˆ์œผ๋ฉฐ,

์‹ค์ œ ์—…๋ฌด์— ์‚ฌ์šฉ๋˜๋Š” ์‹คํ–‰ ๋กœ์ง์€(Job) ์›ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ํด๋ž˜์ŠคํŒŒ์ผ์— ๊ตฌํ˜„ํ•˜๋ฉด๋จ. โžก๏ธ ์Šค์ผ€์ค„๋Ÿฌ๊ฐ€ ์‹คํ–‰ํ•  ๋กœ์ง

(์—ฌ๊ธฐ์„œ๋Š” Myjob.class๋กœ ๋‚˜์˜ค๋ฉฐ, ์Šค์ผ€์ค„๋Ÿฌ๋กœ ๋™์ž‘ํ•  ์„œ๋น„์Šค ๋กœ์ง์ด ์•„๋‹Œ ์Šค์ผ€์ค„๋Ÿฌ ๋“ฑ๋ก์ด ๋ชฉ์ ์ด๋ฏ€๋กœ ์ƒ๋žตํ•˜์˜€์Šต๋‹ˆ๋‹ค.)

 

 

1. pom.xml ์˜์กด์„ฑ ์ฃผ์ž…

<!-- quartz -->
<dependency>
	<groupId>org.quartz-scheduler</groupId>
	<artifactId>quartz</artifactId>
	<version>2.3.0</version>
</dependency>

 

 

2. Quartz ์Šค์ผ€์ค„๋Ÿฌ ๋“ฑ๋ก

์˜ˆ์ œ ํŒŒ์ผ : QuartzConfigTest.java

์Šค์ผ€์ค„๋Ÿฌ๋ฅผ 3๊ฐ€์ง€ ์š”์†Œ๋กœ ๊ตฌ์„ฑํ•ด๋ณด๋ฉด ์Šค์ผ€์ค„๋Ÿฌ & ์‹คํ–‰๋‚ด์šฉ์ธ Job & Job์„ ์‹คํ–‰ํ•  Trigger ์ด๋‹ค.

( ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜๊ณ  ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ์„ค์ •ํ•ด ํ˜ธ์ถœํ•˜๋ฉฐ, ํ˜ธ์ถœํ•  Job ํด๋ž˜์Šค ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๋ฉด ๋!)

์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ๋นˆ์œผ๋กœ ๋“ฑ๋ก ํ•  ๋•Œ ์ž๋ฐ” ๊ธฐ๋ฐ˜์œผ๋กœ ์„ค์ •ํ•ด์ฃผ์—ˆ๋‹ค. Spring์˜ @Configuration ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ ์„ค์ • ํด๋ž˜์Šค๋ฅผ ์ •์˜ ํ•˜๊ณ , @Bean ์–ด๋…ธํ…Œ์ด์…˜์œผ๋กœ SchedulerFactoryBean์„ ์ •์˜ํ•ด ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ์ƒ์„ฑ๋œ ์Šค์ผ€์ค„๋Ÿฌ๋Š” Spring ์ปจํ…์ŠคํŠธ์˜ ์ผ๋ถ€๋กœ ๊ด€๋ฆฌ๋˜๋ฉฐ, ์ž๋™์œผ๋กœ ์ดˆ๊ธฐํ™”๋˜๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ข…๋ฃŒ ์‹œ ์ž๋™์œผ๋กœ ์ข…๋ฃŒ๋œ๋‹ค. 

์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋”ฐ๋ผ๊ฐ€๋ฉฐ ์ž‘์—…(Job)๊ณผ ํŠธ๋ฆฌ๊ฑฐ(Trigger)๋ฅผ ์„ค์ •ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด

JobDetailFactoryBean์œผ๋กœ Quartz ์ž‘์—…์„ ์ •์˜ํ•˜๊ณ , CronTriggerFactoryBean์„ ์‚ฌ์šฉํ•˜์—ฌ ํฌ๋ก  ํ‘œํ˜„์‹์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํŠธ๋ฆฌ๊ฑฐ(์–ธ์ œ ์‹คํ–‰๋ ์ง€)๋ฅผ ์„ค์ •ํ•œ๋‹ค.

import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

@Configuration
public class QuartzConfigTest {
	
    // โ‘  JobDetailFactoryBean ์œผ๋กœ Quartz ์ž‘์—…์˜ ์„ธ๋ถ€ ์ •๋ณด๋ฅผ ์„ค์ •
    @Bean
    public JobDetailFactoryBean jobDetail() {
        JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
        factoryBean.setJobClass(MyJob.class); // ์ž‘์—… ํด๋ž˜์Šค ์„ค์ •
        // ์ž‘์—…์˜ ์ด๋ฆ„, ๊ทธ๋ฃน, ์„ค๋ช…, ๋‚ด๊ตฌ์„ฑ ์—ฌ๋ถ€(durability), ์ €์žฅ ์—ฌ๋ถ€ ๋“ฑ์„ ์„ค์ •
        factoryBean.setDescription("Sample Quartz Job");
        factoryBean.setDurability(true);
        return factoryBean;
    }

    // โ‘ก CronTriggerFactoryBean ์œผ๋กœ ํŠธ๋ฆฌ๊ฑฐ ์„ค์ •(์ž‘์—… ์‹คํ–‰ ์‹œ์ )
    @Bean
    public CronTriggerFactoryBean cronTrigger() {
        CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();
        factoryBean.setJobDetail(jobDetail().getObject());
        factoryBean.setCronExpression("0 0/5 * * * ?"); // ํฌ๋ก ํ‘œํ˜„์‹์œผ๋กœ ๋งค 5๋ถ„๋งˆ๋‹ค ์‹คํ–‰ ์ •์˜
        return factoryBean;
    }

	// โ‘ข SchedulerFactoryBean
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() {
        Properties properties = new Properties(); // Quartz ์Šค๋ ˆ๋“œ ํ’€ ์„ค์ •์„ ์œ„ํ•œ Properties ๊ฐ์ฒด ์ƒ์„ฑ
        // Quartz์˜ ์Šค๋ ˆ๋“œ ํ’€์˜ ํฌ๊ธฐ๋ฅผ 1๋กœ ์ง€์ •. 
        // ์ฆ‰, ์Šค๋ ˆ๋“œ ํ’€์—์„œ ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์‹คํ–‰๋˜๋„๋ก ํ•จ.
        properties.setProperty("org.quartz.threadPool.threadCount", "1"); //Singleton ์Šค๋ ˆ๋“œ ์ฒ˜๋ฆฌ

        // โ˜…SchedulerFactoryBean ๊ฐ์ฒด ์ƒ์„ฑ. 
        // ์ด ๊ฐ์ฒด๋Š” Spring์—์„œ Quartz ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋นˆ์ด๋‹ค.
        SchedulerFactoryBean scheduler = new SchedulerFactoryBean();

        // Quartz ์Šค์ผ€์ค„๋Ÿฌ์— Properties ์ ์šฉ
        scheduler.setQuartzProperties(properties);

        // ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ์Šค์ผ€์ค„๋Ÿฌ์— ์„ค์ • 
        scheduler.setTriggers(cronTrigger().getObject()); 
        // n๊ฐœ์˜ ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ์„ค์ •์‹œ ์‰ผํ‘œ๋กœ ์ด์–ด์„œ ์„ค์ • ๊ฐ€๋Šฅ 
        // ex) firstCronTrigger().getObject(), secondCronTrigger().getObject()

        return scheduler; // ์„ค์ •๋œ SchedulerFactoryBean ๊ฐ์ฒด ๋ฐ˜ํ™˜
    }

}

@Configuration๊ณผ @Bean์˜ ์กฐํ•ฉ์€ ์Šคํ”„๋ง์˜ ํ•ต์‹ฌ์ ์ธ ์„ค์ • ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ œ๊ณตํ•˜๋ฉฐ,  ํŠนํžˆ ํ”„๋ก์‹œ๋ฅผ ํ†ตํ•œ ์‹ฑ๊ธ€ํ†ค ๋ณด์žฅ์ด ๊ฐ€๋Šฅํ•ด์ง‘๋‹ˆ๋‹ค.

@Bean ๋ฉ”์„œ๋“œ์˜ ์—ญํ• : ์ปจํ…Œ์ด๋„ˆ๋Š” @Bean ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ์ฐพ์•„ ํ•ด๋‹น ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ Spring ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…์ŠคํŠธ์— ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

 

โ˜‘  ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋นˆ์„ ๋“ฑ๋กํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ๊ณผ์ •์— ๋Œ€ํ•ด์„œ ํ—ท๊ฐˆ๋ฆฐ๋‹ค๋ฉด ์•„๋ž˜ ๋ธ”๋กœ๊ทธ๋ฅผ ์ถ”์ฒœํ•˜๋ฉฐ ์ถœ์ฒ˜ ๋‚จ๊น๋‹ˆ๋‹ค.

  1. ๋จผ์ € @Configuration์ด ๋ถ™์€ ํด๋ž˜์Šค๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. ์ด ํด๋ž˜์Šค๋“ค์ด ์„ค์ • ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
  2. ๊ทธ๋‹ค์Œ @Component, @Controller, @Service, @Repository ๋“ฑ์˜ ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ํด๋ž˜์Šค๋“ค์„ ์ฐพ์•„์„œ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.
  3. @Bean์ด ๋ถ™์€ ๋ฉ”์„œ๋“œ๋“ค์„ ์ฐพ์•„ ๊ทธ ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ์ฒด๋“ค๋„ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.
  4. ์ด๋ ‡๊ฒŒ ๋“ฑ๋ก๋œ ๋นˆ๋“ค์˜ ์˜์กด๊ด€๊ณ„๋ฅผ ๋ถ„์„ํ•˜๊ณ  ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์ž๋™์œผ๋กœ ์ฃผ์ž…ํ•ด ์ค๋‹ˆ๋‹ค.

โ˜‘  ์ถœ์ฒ˜: https://curiousjinan.tistory.com/entry/deep-dive-spring-container-configuration-and-bean#๋นˆ์˜ ๋ฒ”์œ„(Scope)๋ž€%3F-1 [์˜ค๋Š˜๋„ ๊ฐœ๋ฐœ์ค‘์ž…๋‹ˆ๋‹ค:ํ‹ฐ์Šคํ† ๋ฆฌ]

 

 

3. Job.class ์ƒ์„ฑ

์œ„ ์˜ˆ์ œ ์†Œ์Šค์—์„œ๋Š” MyJob.class๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๊ธฐ๋Šฅํ•˜๊ณ ์ž ํ•˜๋Š” ๋กœ์ง์„ ๊ตฌ์„ฑํ•ด ์ƒ์„ฑํ•˜๋ฉด ๋œ๋‹ค.

(์„œ๋น„์Šค ๋กœ์ง.. ๋ฐ˜๋ณต๋ฌธ์„ ๋Œ๋ฉฐ db๋ฅผ ์กฐํšŒํ•˜์—ฌ ์ฟ ํฐ์„ ๋ฐœ๊ธ‰ํ•œ๋‹ค ๋“ฑ๋“ฑ. ์Šค์ผ€์ค„๋Ÿฌ๊ฐ€ ์‹คํ–‰๋˜๋ฉฐ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•  ๋กœ์ง์„ ์ž‘์„ฑ)

 

 

 

 

โœ… Scheduler ๋“ฑ๋ก ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ๋ฉ”๋ชจ

์Šค์ผ€์ค„๋Ÿฌ๋Š” Quartz์˜ ํ•ต์‹ฌ ์ธํ„ฐํŽ˜์ด์Šค๋กœ, ์žก(Job)์„ ์Šค์ผ€์ค„๋งํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

Quartz ์Šค์ผ€์ค„๋Ÿฌ์—์„œ Scheduler๋ฅผ ์ธ์Šคํ„ด์Šคํ™”ํ•˜๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๋Œ€ํ‘œ์  ์‚ฌ์šฉ๋ฒ•์ด ๋‘๊ฐ€์ง€๊ฐ€ ์žˆ๋Š”๋ฐ 

์ฒซ์งธ, StdSchedulerFactory ๋กœ ์ง์ ‘ ์ธ์Šคํ„ด์Šคํ™” ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๊ณ 

๋‘˜์งธ, ์ด ํฌ์ŠคํŒ…์— ์„ค๋ช…ํ•œ ๋‚ด์šฉ์œผ๋กœ SchedulerFactoryBean ์„ ์‚ฌ์šฉํ•˜์—ฌ ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ Spring ์ปจํ…์ŠคํŠธ์— Bean์œผ๋กœ ๋“ฑ๋กํ•˜๊ณ , ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

๋‘๋ฒˆ์งธ ๋ฐฉ๋ฒ•์ด ๋” ์‰ฝ๊ฒŒ ์Šค์ผ€์ค„๋ง ์ž‘์—…์„ ์„ค์ •ํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•˜์—ฌ ์‚ฌ์šฉํ–ˆ๋Š”๋ฐ ์‹ค์ œ๋กœ ์ฝ”๋“œ ์ž‘์„ฑ ๊ตฌ์กฐ๊ฐ€ ๋‹จ์ผํ™” ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋ฅผ ์•Œ์•„๋ณด๊ธฐ๋„ ์‰ฌ์šด ๊ฒƒ ๊ฐ™๋‹ค.

 

์ฒซ๋ฒˆ์งธ ๋ฐฉ๋ฒ•, StdSchedulerFactory

StdSchedulerFactory๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ง์ ‘ Scheduler ์ธ์Šคํ„ด์Šคํ™” ํ•˜๋Š” ๋ฐฉ๋ฒ•.

๋”๋ณด๊ธฐ

์ด ํŒฉํ† ๋ฆฌ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ Quartz ์„ค์ • ํŒŒ์ผ์„ ์ฝ์–ด ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ์ดˆ๊ธฐํ™” ํ•จ.

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

public class QuartzStdSchedulerExample {
    public static void main(String[] args) {
        try {
        
            // SchedulerFactory๋ฅผ ํ†ตํ•ด ๊ธฐ๋ณธ Scheduler ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
            scheduler.start();

            // ์ž‘์—…(Job) ์ •์˜
            JobDetail job = JobBuilder.newJob(MyJob.class)
                    .withIdentity("myJob", "group1")
                    .build();

            // ํŠธ๋ฆฌ๊ฑฐ ์ •์˜ (10์ดˆ๋งˆ๋‹ค ์‹คํ–‰)
            Trigger trigger = TriggerBuilder.newTrigger()
                    .withIdentity("myTrigger", "group1")
                    .startNow()
                    .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                            .withIntervalInSeconds(10)
                            .repeatForever())
                    .build();

            // ์Šค์ผ€์ค„๋Ÿฌ์— ์ž‘์—…๊ณผ ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ์Šค์ผ€์ค„๋ง
            scheduler.scheduleJob(job, trigger);

            // ๋‹ค๋ฅธ ์ž‘์—… ์ถ”๊ฐ€ ๋˜๋Š” ์Šค์ผ€์ค„๋Ÿฌ ์œ ์ง€ ์ž‘์—… ์ˆ˜ํ–‰...

            // ์Šค์ผ€์ค„๋Ÿฌ ์ข…๋ฃŒ (ํ•„์š”ํ•  ๋•Œ)
            scheduler.shutdown(true);
        } catch (SchedulerException se) {
            se.printStackTrace();
        }
    }
}

 

 

๋‘๋ฒˆ์งธ ๋ฐฉ๋ฒ•,  SchedulerFactoryBean

* Spring์€ SchedulerFactoryBean์„ ํ†ตํ•ด Quartz ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ๊ด€๋ฆฌํ•˜๋ฉฐ, ์ด ๋ฐฉ์‹์€ Spring ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด์—์„œ Quartz ์ž‘์—…์„ ํ†ตํ•ฉ ๊ด€๋ฆฌํ•˜๊ธฐ์— ์ ํ•ฉํ•จ.

https://docs.spring.io/spring-framework/docs/3.2.4.RELEASE_to_4.0.0.M3/Spring%20Framework%203.2.4.RELEASE/org/springframework/scheduling/quartz/SchedulerFactoryBean.html

 

SchedulerFactoryBean

FactoryBean that creates and configures a Quartz org.quartz.Scheduler, manages its lifecycle as part of the Spring application context, and exposes the Scheduler as bean reference for dependency injection. Allows registration of JobDetails, Calendars and T

docs.spring.io

 

@Bean
public SchedulerFactoryBean scheduler(Trigger trigger, JobDetail job, DataSource quartzDataSource) {
    SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
    schedulerFactory.setConfigLocation(new ClassPathResource("quartz.properties"));

    schedulerFactory.setJobFactory(springBeanJobFactory());
    // JobDetail ๋ฐ Trigger ๋“ฑ๋ก
    schedulerFactory.setJobDetails(job);
    schedulerFactory.setTriggers(trigger);
    schedulerFactory.setDataSource(quartzDataSource);
    
    return schedulerFactory;
}

์ด์ œ Spring ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…์ŠคํŠธ๊ฐ€ ์‹œ์ž‘๋  ๋•Œ, SchedulerFactoryBean์ด ์ž๋™์œผ๋กœ Quartz ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  ์‹œ์ž‘ํ•œ๋‹ค. Spring์ด ์Šค์ผ€์ค„๋Ÿฌ์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋ฏ€๋กœ, ๋ณ„๋„์˜ ์ฝ”๋“œ๋กœ ์Šค์ผ€์ค„๋Ÿฌ๋ฅผ ์‹œ์ž‘ํ•˜๊ฑฐ๋‚˜ ์ข…๋ฃŒํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

 

 

 

๋ฐ˜์‘ํ˜•