BackEnd/Spring

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

DEV_SE 2024. 9. 3. 11:39

๐Ÿš€ SchedulerFactoryBean ์„ ํ†ตํ•œ Quartz ์Šค์ผ€์ค„๋Ÿฌ ๋“ฑ๋ก

 

๐Ÿš€ 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๋กœ ๋‚˜์˜ค๋ฉฐ, ํฌ์ŠคํŒ…์˜ ๋ชฉ์ ์ด ์Šค์ผ€์ค„๋Ÿฌ ๋“ฑ๋ก์ด๋ฏ€๋กœ ์„œ๋น„์Šค ๋กœ์ง(ex_์ฟ ํฐ ๋ˆ„๋ฝ ํ™•์ธ ๊ธฐ๋Šฅ ๋“ฑ)์€ ์ƒ๋žตํ•˜์˜€์Šต๋‹ˆ๋‹ค.

 

 

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

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

 

 

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

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

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

( Job ํด๋ž˜์Šค ๊ตฌํ˜„ → JobDetail ๋นˆ ๋“ฑ๋ก → Trigger ๋นˆ ๋“ฑ๋ก → Scheduler ๋นˆ์— Trigger ๋“ฑ๋ก )

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

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

2-1. ๋‹จ์ผ Job ์Šค์ผ€์ค„๋Ÿฌ ๋“ฑ๋ก ์˜ˆ์‹œ

@Configuration
public class TestQuartzConfiguration {
	private static final Logger logger = LoggerFactory.getLogger(QuartzConfiguration.class);

	@Resource(name = "messageSource")
	protected MessageSource primusProperties; // ๊ฐœ์ธ ์„ค์ •ํŒŒ์ผ ์—ฐ๋™ ํ•˜์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค.
	
	// โ‘  JobDetail ๋นˆ ์ƒ์„ฑ - ์‹คํ–‰ํ•  Quartz ์ž‘์—… ์ •๋ณด ์„ค์ •
	@Bean(name = "firstJobDetail")
    public JobDetailFactoryBean firstJobDetail() {
        JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
        factoryBean.setJobClass(MyJob.class); // ์‹คํ–‰ํ•  Job ํด๋ž˜์Šค ์ง€์ •
        factoryBean.setDescription("Sample Quartz Job");	// ์„ค๋ช… ์„ค์ •
        factoryBean.setDurability(true); // ์ž‘์—… ๋‚ด๊ตฌ์„ฑ ์œ ์ง€ (์Šค์ผ€์ค„๋Ÿฌ ์žฌ์‹œ์ž‘ ์‹œ ์œ ์ง€)
        return factoryBean;
    }

    // โ‘ก CronTrigger ๋นˆ ์ƒ์„ฑ - JobDetail ์ฃผ์ž… ๋ฐ›์•„ ํŠธ๋ฆฌ๊ฑฐ ์Šค์ผ€์ค„๋ง ์„ค์ •
    @Bean(name = "firstCronTrigger")
    public CronTriggerFactoryBean firstCronTrigger(@Qualifier("firstJobDetail") JobDetail jobDetail) {
        CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
        
        trigger.setJobDetail(jobDetail); // ์‹คํ–‰ํ•  ์ž‘์—… ์—ฐ๊ฒฐ
        trigger.setCronExpression("0 0/1 * * * ?");	// 1๋ถ„๋งˆ๋‹ค ์‹คํ–‰ํ•˜๋Š” ํฌ๋ก  ํ‘œํ˜„์‹
        trigger.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING); // ์žฌ์‹œ์ž‘ ์‹œ ๋ˆ„๋ฝ ๋ฐฉ์ง€
        return trigger;
    }

    // โ‘ข SchedulerFactoryBean ๋นˆ ์ƒ์„ฑ - ํŠธ๋ฆฌ๊ฑฐ ์ฃผ์ž…๋ฐ›์•„ ์Šค์ผ€์ค„๋Ÿฌ ๋“ฑ๋ก ๋ฐ ์‹คํ–‰
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(@Qualifier("firstCronTrigger") Trigger firstCronTrigger) {

    	// ๋ฐฐ์น˜ ์‹คํ–‰ ์—ฌ๋ถ€ ํ”„๋กœํผํ‹ฐ ์กฐํšŒ
    	String batchYn = primusProperties.getMessage("Batch_Server_Yn", null, Locale.getDefault());
		logger.info(" - > ํ•ด๋‹น ์„œ๋ฒ„๋Š” ๋ฐฐ์น˜ ์—ฌ๋ถ€๊ฐ€ '{}'์ž…๋‹ˆ๋‹ค.", batchYn);
        
        Properties quartzProperties = new Properties();
        quartzProperties.setProperty("org.quartz.threadPool.threadCount", "1"); // ์Šค๋ ˆ๋“œ ํ’€ ํฌ๊ธฐ 1๋กœ ์ œํ•œ (์‹ฑ๊ธ€์Šค๋ ˆ๋“œ)
        
        SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();

        // ๋ฐฐ์น˜ ์„œ๋ฒ„์ผ ๊ฒฝ์šฐ์—๋งŒ ์Šค์ผ€์ค„๋Ÿฌ ๋“ฑ๋ก ๋ฐ ์‹คํ–‰
        if ("Y".equals(batchYn)) {
        	schedulerFactory.setQuartzProperties(quartzProperties);	// Quartz ์„ค์ • ์ ์šฉ
        	schedulerFactory.setTriggers(firstCronTrigger);	// ํŠธ๋ฆฌ๊ฑฐ ๋“ฑ๋ก
        }
        return schedulerFactory;
    }
}

 

2-2. ๋‹ค์ค‘ Job๊ณผ Trigger๋ฅผ ํ•œ Config์—์„œ ๋“ฑ๋กํ•˜๋Š” ์˜ˆ์‹œ

  • JobDetail๊ณผ CronTrigger๋ฅผ ๊ฐ๊ฐ ์—ฌ๋Ÿฌ ๊ฐœ ์ƒ์„ฑํ•ด์„œ ์ด๋ฆ„์œผ๋กœ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. -> ์—ฌ๊ธฐ์„œ๋Š” first, seconf ๋กœ ๊ตฌ๋ถ„
  • SchedulerFactoryBean์—์„œ ์—ฌ๋Ÿฌ Trigger๋ฅผ ๋ฐฐ์—ด ํ˜•ํƒœ๋กœ ํ•œ๊บผ๋ฒˆ์— ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.
  • @Qualifier๋กœ ์›ํ•˜๋Š” ๋นˆ์„ ์ •ํ™•ํžˆ ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค.
@Configuration
public class MultiQuartzConfiguration {
    
    @Resource(name = "messageSource")
    protected MessageSource primusProperties;

    // ์ฒซ ๋ฒˆ์งธ JobDetail
    @Bean(name = "jobDetailOne")
    public JobDetailFactoryBean jobDetailOne() {
        JobDetailFactoryBean factory = new JobDetailFactoryBean();
        factory.setJobClass(MyJobOne.class);
        factory.setDescription("์ฒซ ๋ฒˆ์งธ Job");
        factory.setDurability(true);
        return factory;
    }

    // ์ฒซ ๋ฒˆ์งธ CronTrigger (1๋ถ„๋งˆ๋‹ค ์‹คํ–‰)
    @Bean(name = "cronTriggerOne")
    public CronTriggerFactoryBean cronTriggerOne(@Qualifier("jobDetailOne") JobDetail jobDetail) {
        CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
        trigger.setJobDetail(jobDetail);
        trigger.setCronExpression("0 0/1 * * * ?");
        trigger.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING);
        return trigger;
    }

    // ๋‘ ๋ฒˆ์งธ JobDetail
    @Bean(name = "jobDetailTwo")
    public JobDetailFactoryBean jobDetailTwo() {
        JobDetailFactoryBean factory = new JobDetailFactoryBean();
        factory.setJobClass(MyJobTwo.class);
        factory.setDescription("๋‘ ๋ฒˆ์งธ Job");
        factory.setDurability(true);
        return factory;
    }

    // ๋‘ ๋ฒˆ์งธ CronTrigger (5๋ถ„๋งˆ๋‹ค ์‹คํ–‰)
    @Bean(name = "cronTriggerTwo")
    public CronTriggerFactoryBean cronTriggerTwo(@Qualifier("jobDetailTwo") JobDetail jobDetail) {
        CronTriggerFactoryBean trigger = new CronTriggerFactoryBean();
        trigger.setJobDetail(jobDetail);
        trigger.setCronExpression("0 0/5 * * * ?");
        trigger.setMisfireInstruction(CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING);
        return trigger;
    }

    // SchedulerFactoryBean - ๋‘ ํŠธ๋ฆฌ๊ฑฐ ๋ชจ๋‘ ๋“ฑ๋ก
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(
            @Qualifier("cronTriggerOne") Trigger cronTriggerOne,
            @Qualifier("cronTriggerTwo") Trigger cronTriggerTwo) {
        
        String batchYn = primusProperties.getMessage("Batch_Server_Yn", null, Locale.getDefault());

        Properties quartzProps = new Properties();
        quartzProps.setProperty("org.quartz.threadPool.threadCount", "1");

        SchedulerFactoryBean scheduler = new SchedulerFactoryBean();

        if ("Y".equals(batchYn)) {
            scheduler.setQuartzProperties(quartzProps);
            scheduler.setTriggers(cronTriggerOne, cronTriggerTwo);
        }
        return scheduler;
    }
}

 

@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 ์ƒ์„ฑ

์œ„ ์„ค์ • ํŒŒ์ผ ์†Œ์Šค์—์„œ factoryBean.setJobClass(MyJob.class); ์™€ ๊ฐ™์ด job์„ ์ง€์ •ํ•ด์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— MyJob.class๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์„œ๋น„์Šค ๋กœ์ง ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ๋œ๋‹ค.

QuartzJobBean์„ ์ƒ์†ํ•˜๋ฉด executeInternal๋งŒ ๊ตฌํ˜„ํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์—, Spring๊ณผ์˜ ํ†ตํ•ฉ์ด ์‰ฌ์›Œ์ง€๊ณ  Job ๊ตฌํ˜„์ด ๊ฐ„๋‹จํ•ด์ง„๋‹ค.

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

MyJob.clas ์˜ˆ์ œ

package com.batch.job;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.QuartzJobBean;

import com.batch.config.QuartzConfiguration;

public class MyJob extends QuartzJobBean {
	private static final Logger logger = LoggerFactory.getLogger(QuartzConfiguration.class);

	@Override
	protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
		
        // TODO Auto-generated method stub
		logger.info("myJob์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.");
		
	}
}

์Šค์ผ€์ค„๋Ÿฌ ์‹คํ–‰ ๋กœ๊ทธ

 

 

 

โœ… 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 ์ž‘์—…์„ ํ†ตํ•ฉ ๊ด€๋ฆฌํ•˜๊ธฐ์— ์ ํ•ฉํ•จ. 

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

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

 

 

 

 

๋ฐ˜์‘ํ˜•