说明:该定时任务架构:springboot + mybatis + mysql + 独立模块
业务逻辑:
1.时间写在数据库,便于修改
2.在执行任务的方法上加定时刷新注解
3.方法内去数据库中获取定时,然后与当前定时做比较,如果相同不做改变;如果不相同修改定时
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.hxh</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>demo</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>5.1.0</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.31</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.31</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.2.1</version> </dependency> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz-jobs</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
application.properties
spring.datasource.name=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/db_01?useSSL=false
spring.datasource.username=root
spring.datasource.password=hxh123456
mybatis.mapper-locations=classpath:mapper/*.xml
server.port=80
logging.level.root=INFO logging.level.org.hibernate=INFO logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE logging.level.org.hibernate.type.descriptor.sql.BasicExtractor=TRACE logging.level.com.itmuch=DEBUG
定时任务工厂类
package com.example.demo.config; import org.quartz.Trigger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.quartz.CronTriggerFactoryBean; import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean; import org.springframework.scheduling.quartz.SchedulerFactoryBean; import com.example.demo.task.ScheduleTask; @Configuration public class QuartzConfigration { /** * * @param task 需要执行的任务 * @return 定时任务工厂类 */ @Bean(name = "jobDetail") public MethodInvokingJobDetailFactoryBean detailFactoryBean(ScheduleTask task) { MethodInvokingJobDetailFactoryBean jobDetailFactoryBean = new MethodInvokingJobDetailFactoryBean(); /* * 是否并发执行 * 例如每5s执行一次任务,但是当前任务还没有执行完,就已经过了5s了, * 如果此处为true,则下一个任务会执行,如果此处为false,则下一个任务会等待上一个任务执行完后,再开始执行 */ jobDetailFactoryBean.setConcurrent(false); jobDetailFactoryBean.setName("detail-name");//设置任务名字 jobDetailFactoryBean.setGroup("a1");//设置任务分组,,这些属性都可以存储在数据库中,在多任务的时候使用 jobDetailFactoryBean.setTargetObject(task);//为需要执行的实体类对应的对象 jobDetailFactoryBean.setTargetMethod("sing");//需要执行task类中的方法 return jobDetailFactoryBean; } /** * Details:配置定时任务的触发器,也就是什么时候触发执行定时任务 * @param jobDetailFactoryBean * @return */ @Bean(name = "jobTrigger") public CronTriggerFactoryBean cronJobTrigger(MethodInvokingJobDetailFactoryBean jobDetailFactoryBean) { CronTriggerFactoryBean triggerFactoryBean = new CronTriggerFactoryBean(); triggerFactoryBean.setJobDetail(jobDetailFactoryBean.getObject()); triggerFactoryBean.setCronExpression("0 30 20 * * ?");// 初始时的cron表达式 triggerFactoryBean.setName("detail-name"); return triggerFactoryBean; } /** * * @param trigger * @return */ @Bean(name = "scheduler") public SchedulerFactoryBean schedulerFactory(Trigger trigger) { SchedulerFactoryBean bean = new SchedulerFactoryBean(); // 用于quartz集群,QuartzScheduler 启动时更新己存在的Job bean.setOverwriteExistingJobs(true); // 延时启动,应用启动1秒后 bean.setStartupDelay(1); // 注册触发器 bean.setTriggers(trigger); return bean; } }
定时任务刷新定时类
package com.example.demo.task; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.forwardedUrl; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import javax.annotation.Resource; import javax.net.ssl.HttpsURLConnection; import org.quartz.CronScheduleBuilder; import org.quartz.CronTrigger; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; importorg.springframework.stereotype.Component; import com.example.demo.dao.QuartzDao; import com.example.demo.entity.Config; @Configuration @EnableScheduling @Component public class ScheduleRefreshDatabase { @Autowired private QuartzDao dao; @Resource(name = "jobDetail") private JobDetail jobDetail; @Resource(name = "jobTrigger") private CronTrigger cronTrigger; @Resource(name = "scheduler") private Scheduler scheduler; @Scheduled(fixedRate = 30000) public void scheduleUpdateCronTrigger() throws SchedulerException, IOException { CronTrigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey()); String currentCron = trigger.getCronExpression(); Config config = new Config(); config.setId(1l); String searchCron = dao.findCron(config); // System.out.println(currentCron); // System.out.println(searchCron); if (currentCron.equals(searchCron)) { // URL url = new URL("http://localhost:8080/ssmredis2/redis/refurbish"); // URLConnection openConnection = url.openConnection(); // openConnection.connect(); // InputStream inputStream = openConnection.getInputStream(); // inputStream.close(); // URL url2 = openConnection.getURL(); // System.out.println(url2); } else { // 表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(searchCron); // 按新的cronExpression表达式重新构建trigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey()); trigger = trigger.getTriggerBuilder().withIdentity(cronTrigger.getKey()) .withSchedule(scheduleBuilder).build(); // 按新的trigger重新设置job执行 scheduler.rescheduleJob(cronTrigger.getKey(), trigger); currentCron = searchCron; }
定时任务方法实现类
package com.example.demo.task; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.stereotype.Component; @Configuration @Component @EnableScheduling public class ScheduleTask { private static Logger LOGGER = LoggerFactory.getLogger(ScheduleTask.class); public void sing() { LOGGER.info("Hello world, i'm sing a song!!!"); } }
文章来源: springboot实现定时任务