All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.kedauis.config.QuartzFactoryConfig Maven / Gradle / Ivy

package com.kedauis.config;

import com.kedauis.common.annotation.AutoQuartz;
import com.kedauis.util.ClasspathPackageScanner;
import org.quartz.JobDetail;
import org.quartz.Trigger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
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;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.text.ParseException;
import java.util.*;

/**
 * 项目名称:kd-uip
 * 类描述:
 * 创建人:QiuYu
 * 创建时间:2018/1/11 9:15
 * 修改人:
 * 修改时间:
 * 修改备注:
 */
@Configuration
@ConfigurationProperties(prefix="spring.quartz")
public class QuartzFactoryConfig {

    private Logger logger = LoggerFactory.getLogger(QuartzFactoryConfig.class);

    private String instanceName;
    private String dbUrl;
    private String dbUser;
    private String dbDriver;
    private String dbPassword;
    private String dbMaxConnections;

    @Autowired
    private ClasspathPackageScanner classpathPackageScanner;

    private Properties quartzProperties() throws IOException {
        Properties prop = new Properties();
        prop.put("quartz.scheduler.instanceName", instanceName);
        prop.put("org.quartz.scheduler.instanceId", "AUTO");
        prop.put("org.quartz.scheduler.skipUpdateCheck", "true");
        prop.put("org.quartz.scheduler.jmx.export", "true");

        prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
        prop.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.StdJDBCDelegate");
        prop.put("org.quartz.jobStore.dataSource", "quartzDataSource");
        prop.put("org.quartz.jobStore.tablePrefix", "T_B_QRTZ_");
        prop.put("org.quartz.jobStore.isClustered", "true");

        prop.put("org.quartz.jobStore.clusterCheckinInterval", "20000");
        prop.put("org.quartz.jobStore.dataSource", "myDS");
        prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
        prop.put("org.quartz.jobStore.misfireThreshold", "120000");
        prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true");
        prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS WHERE LOCK_NAME = ? FOR UPDATE");

        prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
        prop.put("org.quartz.threadPool.threadCount", "10");
        prop.put("org.quartz.threadPool.threadPriority", "5");
        prop.put("org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread", "true");

        prop.put("org.quartz.dataSource.myDS.driver", dbDriver);
        prop.put("org.quartz.dataSource.myDS.URL", dbUrl);
        prop.put("org.quartz.dataSource.myDS.user", dbUser);
        prop.put("org.quartz.dataSource.myDS.password", dbPassword);
        prop.put("org.quartz.dataSource.myDS.maxConnections", dbMaxConnections);

        prop.put("org.quartz.plugin.triggHistory.class", "org.quartz.plugins.history.LoggingJobHistoryPlugin");
        prop.put("org.quartz.plugin.shutdownhook.class", "org.quartz.plugins.management.ShutdownHookPlugin");
        prop.put("org.quartz.plugin.shutdownhook.cleanShutdown", "true");
        return prop;
    }

    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
        SchedulerFactoryBean factory = new SchedulerFactoryBean();
        // 用于quartz集群,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
        factory.setOverwriteExistingJobs(true);
        // QuartzScheduler 延时启动,应用启动完10秒后 QuartzScheduler 再启动
        factory.setStartupDelay(0);
        // 用于quartz集群,加载quartz数据源配置
        factory.setQuartzProperties(quartzProperties());
        factory.setAutoStartup(true);
        factory.setApplicationContextSchedulerContextKey("applicationContext");
        // 注册触发器
        List possibleTasks = classpathPackageScanner.getFullyQualifiedClassNameList();
        List triggers = new ArrayList();
        for(String classPath : possibleTasks){
            try {
                Class clasz = Class.forName(classPath);
                AutoQuartz autoQuartz = (AutoQuartz) clasz.getAnnotation(AutoQuartz.class);
                if(null == autoQuartz){
                    logger.info("对象{}缺失@AutoQuartz配置,不是一个有效的定时任务对象!", classPath);
                    continue;
                }
                Service service = (Service) clasz.getAnnotation(Service.class);
                if(null == service){
                    logger.info("对象{}缺失@Service配置,不是一个有效的定时任务对象!");
                    continue;
                }
                JobDetailFactoryBean jobDetailFactoryBean = createJobDetail(autoQuartz.group(), service.value(), autoQuartz.method(), autoQuartz.task());
                jobDetailFactoryBean.setBeanName(autoQuartz.task());
                jobDetailFactoryBean.afterPropertiesSet();
                JobDetail jobDetail = jobDetailFactoryBean.getObject();
                CronTriggerFactoryBean cronTriggerFactoryBean = dialogStatusTrigger(jobDetail, autoQuartz.cron());
                cronTriggerFactoryBean.setBeanName(autoQuartz.task());
                cronTriggerFactoryBean.afterPropertiesSet();
                Trigger cronJobTrigger = cronTriggerFactoryBean.getObject();
                triggers.add(cronJobTrigger);
                logger.info("定时任务工厂注册任务:{} | {} | {} | {} | {}", classPath, autoQuartz.group(), service.value(), autoQuartz.method(),autoQuartz.cron());
            } catch (ClassNotFoundException e) {
                logger.info("对象[{}]未找到", classPath);
                continue;
            } catch (ParseException e) {
                logger.info("触发器[{}]创建出现异常", "CronTriggerFactoryBean");
                continue;
            }
        }

        factory.setTriggers(triggers.toArray(new Trigger[]{}));
        // 直接使用配置文件
        // factory.setConfigLocation(new FileSystemResource(this.getClass().getResource("/quartz.properties").getPath()));
        return factory;
    }


    private static JobDetailFactoryBean createJobDetail(String groupName, String targetObject, String targetMethod, String targetTask) {
        JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
        factoryBean.setJobClass(InvokingJobDetailDetailFactory.class);
        factoryBean.setDurability(true);
        factoryBean.setRequestsRecovery(true);
        factoryBean.setGroup(groupName);
        Map map = new HashMap();
        map.put("targetObject", targetObject);
        map.put("targetMethod", targetMethod);
        map.put("targetTask", targetTask);
        factoryBean.setJobDataAsMap(map);
        return factoryBean;
    }

    // 创建触发器工厂
    private static CronTriggerFactoryBean dialogStatusTrigger(JobDetail jobDetail, String cronExpression) {
        CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();
        factoryBean.setJobDetail(jobDetail);
        factoryBean.setCronExpression (cronExpression);
        return factoryBean;
    }

    public String getInstanceName() {
        return instanceName;
    }

    public void setInstanceName(String instanceName) {
        this.instanceName = instanceName;
    }

    public String getDbUrl() {
        return dbUrl;
    }

    public void setDbUrl(String dbUrl) {
        this.dbUrl = dbUrl;
    }

    public String getDbUser() {
        return dbUser;
    }

    public void setDbUser(String dbUser) {
        this.dbUser = dbUser;
    }

    public String getDbDriver() {
        return dbDriver;
    }

    public void setDbDriver(String dbDriver) {
        this.dbDriver = dbDriver;
    }

    public String getDbPassword() {
        return dbPassword;
    }

    public void setDbPassword(String dbPassword) {
        this.dbPassword = dbPassword;
    }

    public String getDbMaxConnections() {
        return dbMaxConnections;
    }

    public void setDbMaxConnections(String dbMaxConnections) {
        this.dbMaxConnections = dbMaxConnections;
    }

    public ClasspathPackageScanner getClasspathPackageScanner() {
        return classpathPackageScanner;
    }

    public void setClasspathPackageScanner(ClasspathPackageScanner classpathPackageScanner) {
        this.classpathPackageScanner = classpathPackageScanner;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy