如何解决如何使用 ddbb 表在 SpringBoot 上从石英执行多个作业
我是石英的新手,我将它与 springboot 一起使用以自动运行任务。目前我有一个虚拟任务要运行。我的想法是从数据库中的一个表中取出将要执行的所有进程,在该表中将存储 cron 表达式。我分享我目前开发的内容:
我已将相应的库添加到pom.xml
:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
<version>2.4.2</version>
</dependency>
我创建了我理解的 AutoWiringSpringBeanJobFactory.java
类,它用于将石英与 Spring 上下文集成并能够使用依赖注入
public class AutoWiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware{
private transient AutowireCapablebeanfactory beanfactory;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException{
beanfactory=applicationContext.getAutowireCapablebeanfactory();
}
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle)throws Exception
{
final Object job = super.createJobInstance(bundle);
beanfactory.autowireBean(job);
return job;
}
}
我创建了 QuartzConfig.java
类,据我所知,它将管理 JobsDetail、触发器和安排它们
@Configuration
public class QuartzConfig {
private static Logger LOGGER = LogManager.getLogger(QuartzConfig.class);
private ApplicationContext applicationContext;
private DataSource dataSource;
public QuartzConfig(ApplicationContext applicationContext,DataSource dataSource) {
this.applicationContext = applicationContext;
//this.dataSource = dataSource;
}
/**
*
* @return jobFactory a Factory for build jobs base on AutoWiring
*/
@Bean
public SpringBeanJobFactory springBeanJobFactory() {
AutoWiringSpringBeanJobFactory jobFactory = new AutoWiringSpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
return jobFactory;
}
/**
*
* @param triggers allow array of triggers
* @return factory for build schedulers
*/
@Bean
public Schedulerfactorybean scheduler(Trigger... triggers) {
Schedulerfactorybean schedulerFactory = new Schedulerfactorybean();
Properties properties = new Properties();
//Seteamos el identificador de la instancia
properties.setProperty("org.quartz.scheduler.instanceId",String.valueOf(UUID.randomUUID()));
properties.setProperty("org.quartz.scheduler.instanceName","CORESE_AUTO");
//properties.setProperty("org.quartz.scheduler.skipUpdateCheck","true");
//properties.setProperty("org.quartz.scheduler.jobFactory.class","org.quartz.simpl.SimpleJobFactory");
//properties.setProperty("org.quartz.threadPool.class","org.quartz.simpl.SimpleThreadPool");
//properties.setProperty("org.quartz.threadPool.threadCount","5");
//properties.setProperty("org.quartz.jobStore.class","org.quartz.simpl.RAMJobStore");
schedulerFactory.setoverwriteExistingJobs(true);
schedulerFactory.setAutoStartup(true);
schedulerFactory.setQuartzProperties(properties);
schedulerFactory.setDataSource(dataSource);
schedulerFactory.setJobFactory(springBeanJobFactory());
schedulerFactory.setWaitForJobsToCompleteOnShutdown(true);
if (ArrayUtils.isNotEmpty(triggers)) {
schedulerFactory.setTriggers(triggers);
}
return schedulerFactory;
}
/**
*
* @param jobDetail object that contain details about of job
* @param pollFrequencyMs Frequency in milliseconds
* @param triggerName name of the triggers
* @return factorybean Factory that allow build triggers
*/
static SimpleTriggerfactorybean createTrigger(JobDetail jobDetail,long pollFrequencyMs,String triggerName) {
LOGGER.debug("createTrigger(jobDetail={},pollFrequencyMs={},triggerName={})",jobDetail.toString(),pollFrequencyMs,triggerName);
SimpleTriggerfactorybean factorybean = new SimpleTriggerfactorybean();
factorybean.setJobDetail(jobDetail);
factorybean.setStartDelay(0L);
factorybean.setRepeatInterval(pollFrequencyMs);
factorybean.setName(triggerName);
factorybean.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY);
factorybean.setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT);
return factorybean;
}
/**
*
* @param jobDetail object that contain details about of job
* @param cronExpression
* @param triggerName
* @return Factory that allow build a crontrigger
*/
static crontriggerfactorybean createcrontrigger(JobDetail jobDetail,String cronExpression,String triggerName) {
LOGGER.debug("createcrontrigger(jobDetail={},cronExpression={},cronExpression,triggerName);
// To fix an issue with time-based cron jobs
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.SECOND,0);
calendar.set(Calendar.MILLISECOND,0);
crontriggerfactorybean factorybean = new crontriggerfactorybean();
factorybean.setJobDetail(jobDetail);
factorybean.setCronExpression(cronExpression);
factorybean.setStartTime(calendar.getTime());
factorybean.setStartDelay(0L);
factorybean.setName(triggerName);
factorybean.setMisfireInstruction(crontrigger.MISFIRE_INSTRUCTION_DO_nothing);
return factorybean;
}
/**
*
* @param jobClass the class that contain a Job for execution
* @param jobName Name of job
* @return Factory that allow build a jobs details
*/
static JobDetailfactorybean createJobDetail(Class jobClass,String jobName) {
LOGGER.debug("createJobDetail(jobClass={},jobName={})",jobClass.getName(),jobName);
JobDetailfactorybean factorybean = new JobDetailfactorybean();
factorybean.setName(jobName);
factorybean.setJobClass(jobClass);
factorybean.setDurability(true);
return factorybean;
}
}
最后我创建了 QuartzSchedulerJobs.java class
,它是指作业并使用前一个类的方法,它将安排它们运行
@Configuration
public class QuartzSchedulerJobs {
@Value("${billing.cron}")
private String CRON_BILLING;
Logger log = LoggerFactory.getLogger(getClass());
List<Proceso> procesos;
/**
*
* @return a job of a specifi class
*/
/***I create the JobDetail for first process***/
@Bean(name = "jobProcess1")
public JobDetailfactorybean jobAnsCandidato() {
return QuartzConfig.createJobDetail(Process1.class,"Class billing Job");
}
/***I create the Trigger for the job of the first process***/
@Bean(name = "triggerProcess1")
public crontriggerfactorybean triggerANSCandidato(@Qualifier("jobProcess1") JobDetail jobDetail) {
return QuartzConfig.createcrontrigger(jobDetail,CRON_BILLING,"Class Billing Trigger");
}
/***I create the JobDetail for second process***/
@Bean(name = "jobProceso2")
public JobDetailfactorybean jobMemberClassBilling() {
return QuartzConfig.createJobDetail(Proceso2Job.class,"Proceso 2 Job");
}
/***I create the Trigger for the job of the second process***/
@Bean(name = "TriggerProceso2")
public crontriggerfactorybean triggerMemberClassBilling(@Qualifier("jobProceso2") JobDetail jobDetail) {
return QuartzConfig.createcrontrigger(jobDetail,"Proceso 2 Job");
}
}
如你所见,如果我想添加任何进程,我必须调用这2个方法
public JobDetailfactorybean jobAnsCandidate ()
和 public crontriggerfactorybean triggerANSCandidate (@Qualifier ("jobAnsCandidate") JobDetail jobDetail)
,我的想法是将所有进程放在我的数据库中的一个表中,并基于该表,根据需要创建尽可能多的 jobDetail 和触发器,如下所示:
public QuartzSchedulerJobs() throws ClassNotFoundException,InstantiationException,illegalaccessexception
{
//All active processes are obtained from the DB
this.procesos=procesosRepository.obtieneProcesosActivos();
//we cycle through the returned records
for(Proceso proc: this.procesos)
{
//We instantiate the class of the job to be executed or obtained from the database itself
Object tempClass = Class.forName(proc.getJobIdentity()).newInstance();
//We create the jobDetails and triggers sending the cron expression as a dynamic parameter
JobDetailfactorybean factorybean=QuartzConfig.createJobDetail(tempClass.getClass(),proc.getJobIdentity());
QuartzConfig.createcrontrigger(factorybean.getobject(),proc.getCronExpr(),"Algo");
}
}
我已经试过了,但它不起作用:(,我会继续寻找是否能找到任何东西,但如果您能帮助我,我将不胜感激。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。