当前位置:网站首页>Implementation of dynamic timer for quartz
Implementation of dynamic timer for quartz
2022-06-28 23:35:00 【Encounter in the evening wind】
1. Basic environment configuration
1.1 quartz Scheduling framework built-in table
Get into quartz Its official website http://www.quartz-scheduler.org/, Click on Downloads. Run in the database quartz Catalog \docs\dbTables Under the tables_mysql.sql
1.2pom rely on
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.8</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>2. Dynamic timing task configuration implementation
2.1 Custom business table
-- Be careful :job_name The full path of the stored task class , stay quartz Pass through jobName and jobGroup To make sure trigger Uniqueness , So these two columns are the joint unique index
create table t_schedule_trigger
(
id int primary key auto_increment, -- ID
cron varchar(200) not null, -- Time expression
status char(1) not null, -- Using a state 0: Ban 1: Enable
job_name varchar(200) not null, -- The name of the task
job_group varchar(200) not null, -- Task groups
unique index(job_name,job_group)
);
-- Additional parameters added to the task
create table t_schedule_trigger_param
(
param_id int primary key auto_increment, -- ID
name varchar(200) not null, -- Parameter name
value varchar(512), -- Parameter values
schedule_trigger_id int not null, -- Foreign keys : quote t_schedule_trigger(id)
foreign key(schedule_trigger_id) references t_schedule_trigger(id)
);2.2quartz.properties( Change the default data source )
org.quartz.scheduler.instanceName:DefaultQuartzScheduler
org.quartz.scheduler.instanceId=AUTO
org.quartz.scheduler.rmi.export:false
org.quartz.scheduler.rmi.proxy:false
org.quartz.scheduler.wrapJobExecutionInUserTransaction:false
org.quartz.threadPool.class:org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=10
org.quartz.threadPool.threadPriority:5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread:true
org.quartz.jobStore.misfireThreshold:60000
org.quartz.jobStore.class:org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties:true
org.quartz.jobStore.tablePrefix:qrtz_
org.quartz.jobStore.dataSource:qzDS
org.quartz.jobStore.isClustered=true
org.quartz.dataSource.qzDS.connectionProvider.class:com.wyy.cp.util.DruidConnectionProvider
org.quartz.dataSource.qzDS.driver:com.mysql.cj.jdbc.Driver
org.quartz.dataSource.qzDS.URL:jdbc:mysql://127.0.0.1:3306/eshop?useUnicode=true&serverTimezone=Asia/Shanghai&useSSL=false&characterEncoding=utf-8
org.quartz.dataSource.qzDS.user:root
org.quartz.dataSource.qzDS.password:123456
org.quartz.dataSource.qzDS.maxConnection:102.3 DruidConnectionProvider.java( Data source extension class )
package com.wyy.cp.util;
import com.alibaba.druid.pool.DruidDataSource;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
import org.quartz.utils.ConnectionProvider;
import java.sql.Connection;
/*
#============================================================================
# JDBC
#============================================================================
org.quartz.jobqzDS.connectionProvider.class:com.zking.q03.quartz.DruidConnectionProvider
org.quartz.dataSourStore.driverDelegateClass:org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties:false
org.quartz.jobStore.dataSource:qzDS
#org.quartz.dataSource.qzDS.connectionProvider.class:org.quartz.utils.PoolingConnectionProvider
org.quartz.dataSource.ce.qzDS.driver:com.mysql.jdbc.Driver
org.quartz.dataSource.qzDS.URL:jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8
org.quartz.dataSource.qzDS.user:root
org.quartz.dataSource.qzDS.password:root
org.quartz.dataSource.qzDS.maxConnections:30
org.quartz.dataSource.qzDS.validationQuery: select 0
*/
/**
* Druid The connection pool Quartz The extension class
*
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class DruidConnectionProvider implements ConnectionProvider {
/**
* Constant configuration and quartz.properties Of documents key bring into correspondence with ( Remove the prefix )
* At the same time provide set Method ,Quartz The frame automatically injects values .
*/
/**
* JDBC drive
*/
public String driver;
/**
* JDBC Connection string
*/
public String URL;
/**
* Database user name
*/
public String user;
/**
* Database user password
*/
public String password;
/**
* Maximum number of database connections
*/
public int maxConnection;
/**
* database SQL The query returns to the connection pool every time , To make sure it's still valid
*/
public String validationQuery;
private boolean validateOnCheckout;
private int idleConnectionValidationSeconds;
public String maxCachedStatementsPerConnection;
private String discardIdleConnectionsSeconds;
public static final int DEFAULT_DB_MAX_CONNECTIONS = 10;
public static final int DEFAULT_DB_MAX_CACHED_STATEMENTS_PER_CONNECTION = 120;
/**
* Druid Connection pool
*/
private DruidDataSource datasource;
@Override
@SneakyThrows
public Connection getConnection() {
return datasource.getConnection();
}
@Override
public void shutdown() {
datasource.close();
}
@Override
@SneakyThrows
public void initialize() {
assert this.URL != null : "DB URL cannot be null";
assert this.driver != null : "DB driver class name cannot be null!";
assert this.maxConnection > 0 : "Max connections must be greater than zero!";
datasource = new DruidDataSource();
datasource.setDriverClassName(this.driver);
datasource.setUrl(this.URL);
datasource.setUsername(this.user);
datasource.setPassword(this.password);
datasource.setMaxActive(this.maxConnection);
datasource.setMinIdle(1);
datasource.setMaxWait(0);
datasource.setMaxPoolPreparedStatementPerConnectionSize(DruidConnectionProvider.DEFAULT_DB_MAX_CACHED_STATEMENTS_PER_CONNECTION);
if (this.validationQuery != null) {
datasource.setValidationQuery(this.validationQuery);
if (!this.validateOnCheckout) {
datasource.setTestOnReturn(true);
} else {
datasource.setTestOnBorrow(true);
}
datasource.setValidationQueryTimeout(this.idleConnectionValidationSeconds);
}
}
}2.4 MyJobFactory.java( Solve the problem that the custom job class is spring The problem of Management )
package com.wyy.cp.util;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class MyJobFactory extends AdaptableJobFactory {
private final AutowireCapableBeanFactory autowireCapableBeanFactory;
@Autowired
public MyJobFactory(AutowireCapableBeanFactory autowireCapableBeanFactory) {
this.autowireCapableBeanFactory = autowireCapableBeanFactory;
}
/**
* Rewrite create Job Instance method of the task , solve Job The task cannot be used Spring Medium Bean problem
*/
@Override
@SneakyThrows
protected Object createJobInstance(TriggerFiredBundle bundle) {
Object jobInstance = super.createJobInstance(bundle);
autowireCapableBeanFactory.autowireBean(jobInstance);
return super.createJobInstance(bundle);
}
}2.5 QuartzConfiguration.java(quartz Scheduling framework and spring Configuration classes for framework integration , The main thing is to org.quartz.Scheduler hand spring Conduct management )
package com.wyy.cp.util;
import lombok.SneakyThrows;
import org.quartz.Scheduler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import java.util.Properties;
@Configuration
public class QuartzConfiguration {
private final MyJobFactory myJobFactory;
@Autowired
public QuartzConfiguration(MyJobFactory myJobFactory) {
this.myJobFactory = myJobFactory;
}
/**
* Create scheduler factory
*/
@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
//1. establish SchedulerFactoryBean
SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
//2. Load custom quartz.properties The configuration file
factoryBean.setQuartzProperties(quartzProperties());
//3. Set up MyJobFactory
factoryBean.setJobFactory(myJobFactory);
return factoryBean;
}
@Bean
@SneakyThrows
public Properties quartzProperties() {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
@Bean
public Scheduler scheduler() {
return schedulerFactoryBean().getScheduler();
}
}
2.6 application.yml
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/eshop?useUnicode=true&serverTimezone=Asia/Shanghai&useSSL=false&characterEncoding=utf-8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.alibaba.druid.pool.DruidDataSource
druid:
initial-size: 5 # Initialization size
min-idle: 10 # Minimum connections
max-active: 20 # maximum connection
max-wait: 60000 # Get the maximum waiting time for a connection
min-evictable-idle-time-millis: 300000 # The minimum lifetime of a connection in the pool , In milliseconds
time-between-eviction-runs-millis: 60000 # How often do I detect idle connections that need to be closed , In milliseconds
filters: stat # Configure extensions :stat- Monitoring statistics ,log4j- journal ,wall- A firewall ( prevent SQL Inject ), After removal , Monitoring interface sql Unable to statistics ,wall
validation-query: SELECT 1 # Check if the connection is valid SQL sentence , When empty, none of the following three configurations are valid
test-on-borrow: true # Execute on connection request validationQuery Check whether the connection is valid , Default true, When turned on, performance will be reduced
test-on-return: true # Execute... When returning the connection validationQuery Check whether the connection is valid , Default false, When turned on, performance will be reduced
test-while-idle: true # When applying for a connection, if the idle time is greater than timeBetweenEvictionRunsMillis, perform validationQuery Check whether the connection is valid , Default false, Recommended Opening , No performance impact
stat-view-servlet:
enabled: true # Open or not StatViewServlet
allow: 127.0.0.1 # Visit the monitoring page White list , Default 127.0.0.1
deny: 192.168.56.1 # Visit the monitoring page The blacklist
login-username: admin # Visit the monitoring page Login account
login-password: 123 # Visit the monitoring page password
filter:
stat:
enabled: true # Open or not FilterStat, Default true
log-slow-sql: true # Open or not slow SQL Record , Default false
slow-sql-millis: 5000 # slow SQL Standards for , Default 3000, Company : millisecond
merge-sql: false # Merging monitoring data from multiple connection pools , Default false
freemarker:
# Appoint HttpServletRequest Whether the properties of can be overridden controller Of model With the same name
allow-request-override: false
#req visit request
request-context-attribute: req
# Suffix name freemarker The default suffix is .ftl, Of course, you can also change your habit .html
suffix: .ftl
# Set the content type of the response
content-type: text/html;charset=utf-8
# Whether to allow mvc Use freemarker
enabled: true
# Open or not template caching
cache: false
# Set the loading path of the template , Multiple separated by commas , Default : [“classpath:/templates/”]
template-loader-path: classpath:/templates/
# Set up Template The coding
charset: UTF-8
logging:
level:
com.wyy.cp.mapper: debug2.7 The task class
package com.wyy.cp.jop;
import ch.qos.logback.core.net.SyslogOutputStream;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class Myjob implements Job {
@Override
public void execute(JobExecutionContext Context) throws JobExecutionException {
Object name = Context.getJobDetail().getJobDataMap().get("name");
Object add = Context.getJobDetail().getJobDataMap().get("add");
System.out.println(name+" Doing "+add+" health !!!!!!!");
}
}
3 Business code
3.1 ScheduleTriggerDataMapper.java
package com.wyy.cp.mapper;
import com.wyy.cp.pojo.ScheduleTriggerData;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.common.Mapper;
@Repository
public interface ScheduleTriggerDataMapper extends Mapper<ScheduleTriggerData> {
}
3.2 ScheduleTriggerMapper .java
package com.wyy.cp.mapper;
import com.wyy.cp.pojo.ScheduleTrigger;
import org.springframework.stereotype.Repository;
import tk.mybatis.mapper.common.Mapper;
@Repository
public interface ScheduleTriggerMapper extends Mapper<ScheduleTrigger> {
}
3.3 ScheduleTriggerDataServiceImpl.java
package com.wyy.cp.Service;
import com.wyy.cp.mapper.ScheduleTriggerDataMapper;
import com.wyy.cp.pojo.ScheduleTriggerData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;
import java.util.List;
@Service
@Primary
public class ScheduleTriggerDataServiceImpl implements ScheduleTriggerDataService {
@Autowired
private ScheduleTriggerDataMapper TriggerDataMapper;
@Override
public List<ScheduleTriggerData> getdata(Long TriggerId) {
Example example=new Example(ScheduleTriggerData.class);
example.createCriteria().andEqualTo("triggerId",TriggerId);
return TriggerDataMapper.selectByExample(example);
}
}
3.4 ScheduleTriggerMapper .java
package com.wyy.cp.Service;
import com.wyy.cp.mapper.ScheduleTriggerMapper;
import com.wyy.cp.pojo.ScheduleTrigger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@Primary
public class ScheduleTriggerServiceImpl implements ScheduleTriggerService {
@Autowired
private ScheduleTriggerMapper triggerMapper;
@Override
public List<ScheduleTrigger> getAll() {
return triggerMapper.selectAll();
}
}
4 Dynamic timing task implementation
package com.wyy.cp.util;
import com.wyy.cp.Service.ScheduleTriggerDataService;
import com.wyy.cp.Service.ScheduleTriggerService;
import com.wyy.cp.pojo.ScheduleTrigger;
import com.wyy.cp.pojo.ScheduleTriggerData;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.xml.ws.soap.Addressing;
import java.util.List;
@Component
public class QuartzTask {
@Autowired
private ScheduleTriggerService triggerService;
@Autowired
private ScheduleTriggerDataService triggerDataService;
@Autowired
private Scheduler scheduler;
@Scheduled(cron = "0/10 * * * * ?")
public void select() throws Exception{
List<ScheduleTrigger> all = triggerService.getAll();
for (ScheduleTrigger t: all) {
// To judge whether or not to be Quartz management
CronTrigger trigger = (CronTrigger) scheduler.getTrigger(TriggerKey.triggerKey(t.getJobName(), t.getJobGroup()));
if(trigger==null){
if(t.getStatus().equals("1")){
JobDetail jobDetail=JobBuilder
.newJob((Class<? extends Job>) Class.forName(t.getJobName()))
.withIdentity(t.getJobName(),t.getJobGroup())
.build();
JobDataMap jobDataMap = jobDetail.getJobDataMap();
List<ScheduleTriggerData> getdata = triggerDataService.getdata(t.getId());
for (ScheduleTriggerData data:getdata ) {
jobDataMap.put(data.getName(),data.getValue());
}
trigger= TriggerBuilder.newTrigger()
.withIdentity(t.getJobName(),t.getJobGroup())
.withSchedule(CronScheduleBuilder.cronSchedule(t.getCron()))
.build();
scheduler.scheduleJob(jobDetail,trigger);
}
}
}
}
}
边栏推荐
- 第三章 处理机调度练习
- 【狀態機設計】Moore、Mealy狀態機、三段式、二段式、一段式狀態機書寫規範
- Yes, use local_ setup. Bash or setup bash
- 第二章 经典同步练习作业
- C interview questions_ 20220627 record
- 第五章 虚拟存储器 练习
- Windows10 phpstudy installing redis extension
- Interviewer: what is the internal implementation of strings in redis?
- scrapy保存数据到excel:利用openpyxl创建多张表,设置Excel行数限制
- IO playback function of FIO
猜你喜欢

stm32F407-------NVIC中断优先级管理

The secondary market is full of bad news. How should the market go next? One article will show you the general trend

融云通信解决方案 破解企业沟通痛点

【Word 教程系列第 2 篇】Word 中如何设置每页的表格都有表头

One card can sell tens of millions, and the business expansion is faster than that of players: you don't understand the Jianghu of star cards
![[state machine design] Moore, Mealy state machine, three-stage, two-stage and one-stage state machine writing specification](/img/48/e29f34aff7cc437bfb574591d54e3d.png)
[state machine design] Moore, Mealy state machine, three-stage, two-stage and one-stage state machine writing specification

第五章 虚拟存储器 练习

Chapter III processor scheduling exercise

Learning fuzzy from SQL injection to bypass the latest safe dog WAF
![[stm32 HAL库] 串口通信](/img/2c/23a2ecf75141b8f38ab99ac6b2eaef.png)
[stm32 HAL库] 串口通信
随机推荐
IDC: Alibaba cloud ranks first in the market share of China's data governance platform in 2021
Yes, use local_ setup. Bash or setup bash
[chapter 71 of the flutter problem series] mutual conversion between uint8list and image in flutter
ERROR 1067 (42000): Invalid default value for ‘end_time‘ Mysql
stm32F407-------通用定时器
The secondary market is full of bad news. How should the market go next? One article will show you the general trend
stm32F407-------RTC实时时钟
[opencv] - linear filtering: box filtering, mean filtering, Gaussian filtering
scrapy保存数据到excel:利用openpyxl创建多张表,设置Excel行数限制
Do you know all the wonderful functions of the vlookup function?
Advice to friends
【OpenCV】—线性滤波:方框滤波、均值滤波、高斯滤波
Don't ask me how to do UI automation test again
stm32F407-------LCD
Is it difficult to register stocks and open accounts online? Is it safe to open an account online?
第五章 虚拟存储器 练习
Langage C - analyse des mots
移动端异构运算技术 - GPU OpenCL 编程(基础篇)
是使用local_setup.bash 还是 setup.bash
Oil monkey script learning