当前位置:网站首页>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);
}
}
}
}
}
边栏推荐
- CMake教程(一)
- Is it safe to open a stock account on the Internet?
- Insomnia last night
- 【Word 教程系列第 1 篇】如何去除 Word 表格中的箭头
- With a monthly salary of 60000 yuan, such people began to be robbed after the Internet "reduced costs and increased efficiency"
- ERROR 1067 (42000): Invalid default value for ‘end_ time‘ Mysql
- Huawei's level 22 experts have worked hard for ten years to complete the advanced practical document of cloud native service grid. 6
- 这样学习二叉树
- The secondary market is full of bad news. How should the market go next? One article will show you the general trend
- C語言-單詞分析解析
猜你喜欢

window10 phpstudy 安装redis扩展

Machine learning 6-decision tree
![[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

【Word 教程系列第 1 篇】如何去除 Word 表格中的箭头

老家出资,俞敏洪设立两支基金

Learning fuzzy from SQL injection to bypass the latest safe dog WAF
![[opencv] - linear filtering: box filtering, mean filtering, Gaussian filtering](/img/1d/3a46517cbfa90005a15d7858d81ca9.png)
[opencv] - linear filtering: box filtering, mean filtering, Gaussian filtering

With a monthly salary of 60000 yuan, such people began to be robbed after the Internet "reduced costs and increased efficiency"

note

Machine learning 4-dimension reduction technology
随机推荐
机器学习4-降维技术
机器学习6-决策树
融云通信解决方案 破解企业沟通痛点
ROS2中的行为树 BehaviorTree
Mysql-5.7.30-winx64 installation free download and installation tutorial
Counting sorting and stability of sorting
TDD and automated testing
没找到实习,他总结了这些
Windows10 phpstudy installing redis extension
fio的IO重放功能
【狀態機設計】Moore、Mealy狀態機、三段式、二段式、一段式狀態機書寫規範
[SSM] an error is reported that the user name of the access denied for user 'WYF' @ 'localhost' (using password: yes) data becomes the user name of the computer
[Chapter 2 of word tutorial series] how to set the table on each page to have a header in word
note
大三,不简单啊!
百度知道爬虫,根据问题id,线索id,评论id获取评论下面的对话
第三章 处理机调度练习
Three communication skills in software testing
urllib. Parse parses the parameters in the URL connection
Solve the problem of Chinese parsing by configparser