1. Api-based approach

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class SpringQuartzApplication implements CommandLineRunner{

    public static void main(String[] args) {
        SpringApplication.run(SpringQuartzApplication.class, args);
    }


    @Override
    public void run(String... args) throws Exception { Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); JobDetail job = JobBuilder.newJob(MyJob.class).build(); Trigger trigger = TriggerBuilder.newTrigger().startNow().withSchedule(SimpleScheduleBuilder.repeatHourlyForever().withIntervalInMillisecon ds(1000)).build(); scheduler.scheduleJob(job, trigger); scheduler.start(); }}Copy the code

You can actually implement the EnvironmentAware interface, take the Environment object, and inject it.

StdSchedulerFactory factory = new StdSchedulerFactory(new Properties());
Scheduler scheduler = factory.getScheduler();
Copy the code

2. SpringBoot processing

Org. Springframework. Boot. Autoconfigure. Quartz. QuartzAutoConfiguration class – this class implements the function of automatic injection.

He will have an org. Springframework. Scheduling. Quartz. SchedulerFactoryBean instantiation, at the same time, before the return, Will set an interceptor is similar to the org. Springframework. Boot. Autoconfigure. Quartz. SchedulerFactoryBeanCustomizer, Some SchedulerFactoryBean information can be set…..

The first is application.properties, with the prefix spring.Quartz. Properties and the suffix as before.

spring.quartz.properties.org.quartz.scheduler.instanceName=MyScheduler
spring.quartz.properties.org.quartz.threadPool.threadCount=4
spring.quartz.properties.org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore
spring.quartz.job-store-type=memory
Copy the code

1. We use SchedulerFactoryBeanCustomizer injection.

@Bean
public SchedulerFactoryBeanCustomizer schedulerFactoryBeanCustomizer(a) {
    return new SchedulerFactoryBeanCustomizer() {
        @Override
        public void customize(SchedulerFactoryBean schedulerFactoryBean) {

            Properties properties = new Properties();
            try {
                properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("quartz.properties"));
            } catch (IOException e) {
                e.printStackTrace();
            }
            schedulerFactoryBean.setQuartzProperties(properties);

            JobDetail job = JobBuilder.newJob(MyQuartzJobBean.class).storeDurably().build();
            Trigger trigger = TriggerBuilder.newTrigger().forJob(job).startNow()
                    .withSchedule(SimpleScheduleBuilder.repeatHourlyForever().withIntervalInMilliseconds(1000))
                    .build();
            // 
            schedulerFactoryBean.setJobDetails(job);
            // schedulerFactoryBean.setTriggers(trigger); }}; }Copy the code

2. Direct injection

@Bean
public Trigger schedulerFactoryBean(a) {
    return TriggerBuilder.newTrigger().forJob(jobDetail()).startNow()
            .withSchedule(SimpleScheduleBuilder.repeatHourlyForever().withIntervalInMilliseconds(1000))
            .build();
}

@Bean
public JobDetail jobDetail(a) {
    return JobBuilder.newJob(MyQuartzJobBean.class).storeDurably().build();
}
Copy the code

Note that the JobDetail should be set to storeDurably() to true, or the environment will not work properly

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'quartzScheduler' defined in class path resource [org/springframework/boot/autoconfigure/quartz/QuartzAutoConfiguration.class]: Invocation of init method failed; nested exception is org.quartz.SchedulerException: Jobs added with no trigger must be durable.
Copy the code

3. QuartzJobBean

Org. Springframework. Scheduling. Quartz. QuartzJobBean injection of Bean, this is characteristic, so special,

He implements the org.Quartz.Job interface, which implements specific methods

public abstract class QuartzJobBean implements Job {

	@Override
	public final void execute(JobExecutionContext context) throws JobExecutionException {
		try {
            // Here is the core... This implementation applies the passed-in job data map as bean property values. and delegates to executeInternal afterwards.
			BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
			MutablePropertyValues pvs = new MutablePropertyValues();
			pvs.addPropertyValues(context.getScheduler().getContext());
			pvs.addPropertyValues(context.getMergedJobDataMap());
			bw.setPropertyValues(pvs, true);
		}
		catch (SchedulerException ex) {
			throw new JobExecutionException(ex);
		}
		executeInternal(context);
	}

	protected abstract void executeInternal(JobExecutionContext context) throws JobExecutionException;

}
Copy the code

Assed -in Job data map as bean property values -> Set the contents of the map to the field properties of the bean

@PersistJobDataAfterExecution
@Component
public class MyQuartzJobBean extends QuartzJobBean {

    public static final String USER_NAME = "name";

    private String name;

    public void setName(String name) {
        this.name = name;
    }

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        System.out.println("Name = "+ name); JobDataMap map = context.getJobDetail().getJobDataMap(); map.put(USER_NAME, UUID.randomUUID().toString()); }}Copy the code

Output:

Name = 29f5aff1-52f0 -47eb-be2c-a84bbe638a7a
Name = 828b594e-f918-42ca-93fe-e2321b2bf312
Name = cb268907-ba2a-4bc7-8ca0-f0facd64a8e3
Name = a3553825-2e8b-4f50-b075-0402dfb1ee7a
Name = d0a95144-50e9-49ca-97c3-5730900180d2
Name = 7c6ff206-3611-4264-915a-f188f747bdd8
Copy the code

So it’s ok…

In fact, this is very useful: just this code….

BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.addPropertyValues(context.getScheduler().getContext());
pvs.addPropertyValues(context.getMergedJobDataMap());
bw.setPropertyValues(pvs, true);
Copy the code