この記事では、スケジュールされたタスクを永続的に実装する Springboot Quartz を紹介します。詳細は次のとおりです。最終的な答え: スケジュールされたタスクを実行するために Quartz を使用するのはこれが初めてです。不備があったことをお詫びします。
まず第一に、Springboot プロジェクトでスケジュールされたタスクを実行するのは比較的簡単です。これを実装する最も簡単な方法は、 **@Scheduled アノテーション。次に、アプリケーション起動クラスで @EnableScheduling** を使用して、スケジュールされたタスクを有効にします。
例
@SpringBootApplication @EnableScheduling public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } // cron为每秒执行一次 @Scheduled(cron = "* * * * * ?") public void print(){ System.out.println("执行定时任务"); } }
結果
スケジュールされたタスクの実行
スケジュールされたタスクの実行
スケジュールされたタスクの実行
スケジュールされたタスクの実行task Task
スケジュールされたタスクの実行
スケジュールされたタスクの実行
スケジュールされたタスクの実行
スケジュールされたタスクの実行
単純なスケジュールされたタスクは、cron 式の方法で実行できます。結果は次のようになります。タスクの実行間隔。
ただし、
実際の開発では、多くのタスクがあり、追加などの個別/すべてのタスクを手動で操作する必要があります。開く、停止、続行、その他の操作。すると「Qianniu Class B…」のBGMとともにクォーツが登場。
quartz
統合
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-quartz</artifactId> </dependency>
クォーツの 3 つの要素
は、ジョブ (タスク) のトリガー条件、トリガー時間、トリガー間隔、終了時間などを定義するために使用されます。
##タスクジョブ
実行する特定のタスクの内容使用
Quartz を使用するには、構成ファイルが必要です。デフォルトの構成ファイルquartz.propertiesは、quartz jarパッケージのorg.quartzパッケージの下にあります。quartz.properties# Default Properties file for use by StdSchedulerFactory # to create a Quartz Scheduler Instance, if a different # properties file is not explicitly specified. # # 名字 org.quartz.scheduler.instanceName: DefaultQuartzScheduler org.quartz.scheduler.rmi.export: false org.quartz.scheduler.rmi.proxy: false org.quartz.scheduler.wrapJobExecutionInUserTransaction: false # 实例化ThreadPool时,使用的线程类为SimpleThreadPool 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 # 持久化方式,默认持久化在内存中,后面我们使用db的方式 org.quartz.jobStore.class: org.quartz.simpl.RAMJobStoreデータベースへのquartzタスクの永続化には、公式にいくつかのものが必要です。定義されたデータベース テーブル、テーブルの SQL ファイルは、quartz jar パッケージ内にあります。 座標 org.quartz.impl.jdbcjobstore には、さまざまなデータベースを含む多くの SQL ファイルがあることがわかります。 MySQL を使用します。 SQL ステートメントを手動で実行する必要はありません。後でプロジェクトを開始するときに自動的に初期化されます。 独自のプロパティ ファイルを作成する
# 实例化ThreadPool时,使用的线程类为SimpleThreadPool org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool # threadCount和threadPriority将以setter的形式注入ThreadPool实例 # 并发个数 org.quartz.threadPool.threadCount=10 # 优先级 org.quartz.threadPool.threadPriority=5 org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true org.quartz.jobStore.misfireThreshold=5000 #持久化使用的类 org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX #数据库中表的前缀 org.quartz.jobStore.tablePrefix=QRTZ_ #数据源命名 org.quartz.jobStore.dataSource=qzDS #qzDS 数据源,我们使用hikaricp,默认的是c3p0 org.quartz.dataSource.qzDS.provider=hikaricp org.quartz.dataSource.qzDS.driver=com.mysql.cj.jdbc.Driver org.quartz.dataSource.qzDS.URL=jdbc:mysql://localhost:3306/quartz?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8 org.quartz.dataSource.qzDS.user=root org.quartz.dataSource.qzDS.password=123456 org.quartz.dataSource.qzDS.maxConnections=10デフォルトの接続プールを使用していないので、それを調べてソース コードを取得しましょう。このパッケージ org.quartz.utils の下に PoolingConnectionProvider があります。名前が示すように、接続プール プロバイダー部分のソース コード
public interface PoolingConnectionProvider extends ConnectionProvider { /** The pooling provider. */ String POOLING_PROVIDER = "provider"; /** The c3p0 pooling provider. */ String POOLING_PROVIDER_C3P0 = "c3p0"; /** The Hikari pooling provider. */ String POOLING_PROVIDER_HIKARICP = "hikaricp"; }その後、HikariCpPoolingConnectionProvider クラスが PoolingConnectionProvider を実装します。 org.quartz.impl の下の StdSchedulerFactory で c3p0 を検索すると、
if(poolingProvider != null && poolingProvider.equals(PoolingConnectionProvider.POOLING_PROVIDER_HIKARICP)) { cpClass = "org.quartz.utils.HikariCpPoolingConnectionProvider"; } else { cpClass = "org.quartz.utils.C3p0PoolingConnectionProvider"; }が見つかります。残りを見てみましょう。最初のソース コードの調査は、想像するほど難しくも退屈でもありません (私はそうするのは好きではありません)。ソースコードを読んでみてください))、しかし、このソースコードには小さな達成感があるようです。 トピック チャネルに戻り、application.yml
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver password: 123456 url: jdbc:mysql://localhost:3306/quartz?characterEncoding=UTF8&useSSL=false&serverTimezone=GMT%2B8 username: root quartz: jdbc: initialize-schema: always job-store-type: jdbcinitialize-schema: always プロジェクトを開始するたびに、常にデータベース テーブルを初期化し、テーブルのキー プレースを自動的に作成します。手順としては、まずデータベーステーブルを削除し、再度作成し、テーブルが存在しない場合は例外がスローされますが、その後に生成されるテーブルには影響しません。次回プロジェクトを開始するときは、テーブルが既に作成されているため、存在する場合、例外はスローされません job-store-type: jdbc これはタスク永続タイプです。jdbc を使用する場合、ジョブに Spring オブジェクトを挿入する必要がある場合があります。設定がなければ、ジョブにスプリング オブジェクトを挿入することはできません。注射される。
/** * @author: taoym * @date: 2020/6/4 11:32 * @desc: 一定要自定义JobFactory重写SpringBeanJobFactory的createJobInstance方法,否则在job中是获取不到spring容器中的bean的 */ @Component public class JobFactory extends SpringBeanJobFactory { @Autowired private AutowireCapableBeanFactory beanFactory; /** * 这里覆盖了super的createJobInstance方法,对其创建出来的类再进行autowire */ @Override protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { Object jobInstance = super.createJobInstance(bundle); beanFactory.autowireBean(jobInstance); return jobInstance; } }quartz 設定ファイルの作成
@Configuration public class QuartzConfig { @Autowired private JobFactory jobFactory; /** * 读取quartz.properties 文件 * 将值初始化 * * @return */ @Bean public Properties quartzProperties() throws IOException { PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean(); propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties")); propertiesFactoryBean.afterPropertiesSet(); return propertiesFactoryBean.getObject(); } @Bean public SchedulerFactoryBean schedulerFactoryBean() throws IOException { SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); schedulerFactoryBean.setJobFactory(jobFactory); schedulerFactoryBean.setQuartzProperties(quartzProperties()); return schedulerFactoryBean; } /** * 初始化监听器 * * @return */ @Bean public QuartzInitializerListener executorListener() { return new QuartzInitializerListener(); } @Bean(name = "scheduler") public Scheduler scheduler() throws IOException { return schedulerFactoryBean().getScheduler(); } }トリガー コンポーネントの作成
public class TriggerComponent { /** * @author: taoym * @date: 2020/6/1 10:35 * @desc: 构建cron触发器 */ public static Trigger cronTrigger(String cron) { CronTrigger cronTrigger = TriggerBuilder.newTrigger() .withSchedule(CronScheduleBuilder.cronSchedule(cron).withMisfireHandlingInstructionDoNothing()) .build(); return cronTrigger; } public static Trigger cronTrigger(String cron, JobDataMap jobDataMap) { CronTrigger cronTrigger = TriggerBuilder.newTrigger() .withSchedule(CronScheduleBuilder.cronSchedule(cron).withMisfireHandlingInstructionDoNothing()) .usingJobData(jobDataMap) .build(); return cronTrigger; } }このコンポーネントを使用してトリガーを取得するだけです。 Create Task
@DisallowConcurrentExecution public class TestJob extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException { } }jobExecutionContext ここでは、タスク グループ、タスク名、トリガー グループ、トリガー名、ジョブの詳細などの情報を取得できます。このアノテーションは、同じインスタンス (jobdetail) を単一のスレッドでのみ実行できるようにするためのものです。 job がインターフェース、jobdetail が実装クラス、a が実装クラスの 1 つであることがわかります。ある操作を実行するには 100 秒かかり、指定したタイマーは 50 秒ごとに操作を実行します。実行を通じて 実行するには別のスレッドを開始する必要があります。 DisallowConcurrentExecution を使用すると、 a が操作を完了していない場合、 a はスレッドを開いて現在の操作を実行できなくなります。私の説明が分かりやすいか分かりません! オンデマンドで独自のタスク リストを作成します。私はスケジュールされたタスクを使用してクローラー (小さなクローラー) を作成します。
CREATE TABLE `quartz_job` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '编号', `job_name` varchar(50) DEFAULT '' COMMENT '任务名', `job_group` varchar(50) DEFAULT '' COMMENT '任务组名称', `job_desc` varchar(255) DEFAULT '' COMMENT 'job描述', `cron` varchar(50) DEFAULT '' COMMENT 'cron表达式', `status` tinyint(1) DEFAULT '0' COMMENT '状态', `url` varchar(255) DEFAULT '' COMMENT '请求地址', `param` varchar(255) DEFAULT '' COMMENT '参数', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8;タスクを追加するときは、Quartz を使用せず、単にタスクを追加します。データベース。パニックにならないでください、彼は後で役に立ちます。このテーブルは追加、削除、変更、確認する必要があります。システム内のタスク リストをクエリし、実行を開始する 1 つまたはすべてのタスクを選択します タスクの実行
@Resource private QuartzJobMapper quartzJobMapper; @Autowired private Scheduler scheduler; @Override public String start(Integer id) { JobDataMap jobDataMap = new JobDataMap(); jobDataMap.put(k,v); QuartzJob quartzJob = quartzJobMapper.selectByPrimaryKey(id); JobKey jobKey = JobKey.jobKey(quartzJob.getJobName(), quartzJob.getJobGroup()); jobDetail = JobBuilder.newJob(TestJob.class).withIdentity(jobKey).storeDurably().build(); Trigger trigger = TriggerComponent.cronTrigger(quartzJob.getCron(), jobDataMap); try { scheduler.scheduleJob(jobDetail, trigger); quartzJobMapper.updateStatus(true, id); return "开始任务执行成功"; } catch (SchedulerException se) { log.info("开始任务的时候发生了错误"); } return "开始任务的时候发生了错误,请检查日志"; }最後に、このチュートリアルの内容に従って貼り付けました。コードを渡すと、正常に実行できます。
#
推奨チュートリアル: 「PHP」
以上がspringboot+quartz はスケジュールされたタスクを永続的な方法で実装しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。