1.创建springboot项目
使用Spring Initializr创建一个新的Spring Boot项目,选择Web和Quartz依赖项。
2.添加quartz配置
在application.properties中添加以下配置:
# Quartz settings
spring.quartz.job-store-type=jdbc
spring.quartz.jdbc.initialize-schema=always
spring.quartz.properties.org.quartz.scheduler.instanceName=myScheduler
spring.quartz.properties.org.quartz.scheduler.instanceId=AUTO
spring.quartz.properties.org.quartz.threadPool.threadCount=10
spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX
spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
spring.quartz.properties.org.quartz.jobStore.dataSource=quartzDataSource
spring.quartz.properties.org.quartz.jobStore.tablePrefix=QRTZ_
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/quartz?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=root
这将启用Spring的Quartz支持,并将其配置为使用MySQL数据库。该配置还定义了一个名为myScheduler的调度器实例,并指定将使用线程池来执行任务。
3.创建简单的任务
在src/main/java/com/example/quartzdemo文件夹下创建一个新的Java类,名为SimpleJob.java。将以下代码复制到该类中:
package com.example.quartzdemo;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class SimpleJob implements Job {
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("SimpleJob executed at " + new Date());
}
}
这是一个简单的Quartz任务,它只是在控制台上输出当前时间。
4.创建定时器
在同一文件夹中创建另一个Java类,名为SchedulerConfig.java。将以下代码复制到该类中:
package com.example.quartzdemo;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@Configuration
public class SchedulerConfig {
@Autowired
private ApplicationContext applicationContext;
@Bean
public JobDetail simpleJobDetail() {
return JobBuilder.newJob().ofType(SimpleJob.class)
.storeDurably()
.withIdentity("simpleJob")
.withDescription("Invoke Simple Job service...")
.build();
}
@Bean
public Trigger simpleJobTrigger(JobDetail simpleJobDetail) {
int frequencyInSec = 10;
return TriggerBuilder.newTrigger().forJob(simpleJobDetail)
.withIdentity("simpleTrigger")
.withDescription("Sample trigger")
.withSchedule(
SimpleScheduleBuilder.simpleSchedule()
.withIntervalInSeconds(frequencyInSec)
.repeatForever())
.build();
}
@Bean
public Scheduler scheduler(Trigger simpleJobTrigger, JobDetail simpleJobDetail) throws SchedulerException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setJobFactory(new AutowiringSpringBeanJobFactory(this.applicationContext));
factory.setQuartzProperties(quartzProperties());
factory.afterPropertiesSet();
Scheduler scheduler = factory.getScheduler();
scheduler.scheduleJob(simpleJobDetail, simpleJobTrigger);
return scheduler;
}
@Bean
public Properties quartzProperties() {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
Properties properties = null;
try {
propertiesFactoryBean.afterPropertiesSet();
properties = propertiesFactoryBean.getObject();
} catch (IOException e) {
e.printStackTrace();
}
return properties;
}
}
该类包含了一个名为simpleJobDetail的JobDetail和一个名为simpleJobTrigger的触发器。这些组件定义了我们的Quartz任务应该如何运行。
在此配置中,任务将每隔10秒运行一次。您可以根据需要更改此设置。
5.创建自动装配Spring Bean工厂
在同一文件夹中创建另一个Java类,名为AutowiringSpringBeanJobFactory.java。将以下代码复制到该类中:
package com.example.quartzdemo;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;
public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {
private transient AutowireCapableBeanFactory beanFactory;
public void setApplicationContext(final ApplicationContext context) {
beanFactory = context.getAutowireCapableBeanFactory();
}
@Override
protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
final Object job = super.createJobInstance(bundle);
beanFactory.autowireBean(job);
return job;
}
}
此类是Spring Bean工厂,我们将使用它来自动装配我们的Quartz任务。
6.创建Vue项目
使用vue-cli创建一个新的Vue项目:
vue create my-project
7.添加axios和vuex依赖项
在my-project目录中运行以下命令:
npm install axios vuex --save
8.创建store.js文件
在src/store文件夹下创建store.js文件,并将以下代码复制到该文件中:
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
logs: []
},
mutations: {
PUSH_LOG(state, log) {
state.logs.push(log)
}
},
actions: {
async getLogs({ commit }) {
try {
const response = await axios.get('/api/logs')
const logs = response.data
logs.forEach(log => commit('PUSH_LOG', log))
} catch (error) {
console.log(error)
}
}
}
})
export default store
此代码定义了一个名为logs的状态,该状态包含所有日志信息。还有一个action,它可以从服务器获取所有日志并将它们保存到state中。
9.创建Log.vue组件
在src/components文件夹下创建Log.vue文件,并将以下代码复制到该文件中:
<template>
<div class="log">
<h2>Logs</h2>
<ul>
<li v-for="log in logs" :key="log.id">
{{ log.message }}
</li>
</ul>
</div>
</template>
<script>
export default {
computed: {
logs() {
return this.$store.state.logs
}
},
created() {
this.$store.dispatch('getLogs')
setInterval(() => {
this.$store.dispatch('getLogs')
}, 5000)
}
}
</script>
此代码定义了一个名为Log的组件,该组件会显示所有日志信息。它还定义了一个计算属性logs,该属性从store中获取日志信息。
在created函数中,组件调用getLogs action来获取日志信息,并在每五秒钟刷新一次。
10.创建一个Express服务器
在my-project目录中运行以下命令:
npm install express cors --save
接下来,创建一个新文件夹src/server,并在其中创建一个新文件server.js。将以下代码复制到该文件中:
const express = require('express')
const cors = require('cors')
const app = express()
app.use(cors())
let logs = []
app.get('/api/logs', (req, res) => {
res.json(logs)
})
app.post('/api/logs', (req, res) => {
const message = req.body.message
const log = { id: logs.length + 1, message }
logs.push(log)
res.json(log)
})
app.listen(3000, () => console.log('Server running on port 3000'))
此代码创建一个Express服务器,并定义两个路由:/api/logs和/api/logs(POST)。/api/logs路由将返回所有日志信息,/api/logs(POST)路由将保存新的日志信息。
11.更新Quartz任务
在SimpleJob.java文件中,在execute函数中添加以下代码:
@Autowired
private RestTemplate restTemplate;
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
String message = "SimpleJob executed at " + new Date();
System.out.println(message);
restTemplate.postForObject("http://localhost:3000/api/logs", new Log(message), Log.class);
}
此代码创建一个新的RestTemplate,并使用它来向服务器发送一个POST请求,将日志信息保存到服务器上。请注意,此代码假定服务器正在本地主机上运行。
12.运行应用程序
在my-project目录中运行以下命令以启动Vue应用程序:
npm run serve
打开浏览器并导航到http://localhost:8080,您应该能看到一个包含所有日志信息的列表。
接下来,在IntelliJ IDEA中运行Spring Boot应用程序,您应该能够在控制台上看到每隔10秒钟输出一次时间戳,并且这些信息也会显示在浏览器中。
至此,我们已经成功地实现了一个简单的定时任务,并在前端显示了日志信息。




