spring-boot 如何實(shí)現(xiàn)單次執(zhí)行程序
spring-boot 單次執(zhí)行程序
spring-boot做為spring的集大成框架,大部分時(shí)候作為WEB服務(wù)被集成使用,但某些情況下,需要手動(dòng)執(zhí)行一些邏輯的情況下,單次運(yùn)行的類似腳本的程序也是很有用的。
本文記錄一下使用spring-boot作為單次可執(zhí)行程序配置方式。
pom.xml
注意:pom.xml部分只需引入spring-boot-starter模塊,尤其不要引入web模塊,其他非spring本身模塊可以隨意引入
<?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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<!-- 按工程習(xí)慣處理parent部分 -->
</parent>
<groupId>com.leon</groupId>
<artifactId>sprint-boot-task</artifactId>
<version>0.0.1-SNAPSHOT</version>
<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</artifactId>
<version>2.0.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
主要代碼結(jié)構(gòu)
Service類
@Service
public class StatService {
public void doSomething() {
System.out.println("===================: this is a test service but nothing");
}
}
執(zhí)行邏輯入口類
@Component
public class StatTask {
private StatService statService;
@Autowired
public StatTask(StatService statService) {
this.statService = statService;
}
public void doSomething() {
statService.doSomething();
}
}
Spring-boot 啟動(dòng)類
@SpringBootApplication
public class TaskApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(TaskApplication.class, args);
StatTask statTask = context.getBean(StatTask.class); // 獲取邏輯入口類的實(shí)例
statTask.doSomething();
}
}
如此這般后,啟動(dòng)這個(gè)springboot工程,執(zhí)行完啟動(dòng)類中的調(diào)用過程后,程序就會(huì)自動(dòng)退出。
基本上,不配置啟用spring mvc和定時(shí)Job,這種配置下的springboot就是一個(gè)“腳本”程序。
這里舉個(gè)?,上面的代碼加上兩個(gè)注解,就會(huì)變成常駐進(jìn)程程序:
執(zhí)行邏輯入口類
@Component
public class StatTask {
private StatService statService;
@Autowired
public StatTask(StatService statService) {
this.statService = statService;
}
@Scheduled(fixedRate = 5000L) // --------------這里-----------------
public void doSomething() {
statService.doSomething();
}
}
Spring-boot 啟動(dòng)類
@SpringBootApplication
@EnableScheduling // --------------這里---------------
public class TaskApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(TaskApplication.class, args);
StatTask statTask = context.getBean(StatTask.class);
statTask.doSomething();
}
}
與最上面區(qū)別的是,上面只執(zhí)行一次,輸出 “this is a test service but nothing” 就完事了,進(jìn)程自動(dòng)退出,
加上兩個(gè)注解后就會(huì)每5秒輸出一次 “this is a test service but nothing”,且進(jìn)程永駐。
當(dāng)然這種情況下使用腳本語(yǔ)言如python、nodeJs等可能更好一些,但在其他語(yǔ)言不熟的情況下,使用spring-boot來應(yīng)急也是極好的。
啟動(dòng)時(shí)執(zhí)行單次任務(wù)
最近做任務(wù)遇到一個(gè)問題,需要在項(xiàng)目啟動(dòng)時(shí)候執(zhí)行掃描數(shù)據(jù)庫(kù)表的任務(wù),用于異?;謴?fù)容災(zāi),一開始想的是可不可以使用定時(shí)任務(wù)
代碼如下 并且在啟動(dòng)類加上
@EnableScheduling注解就可以實(shí)現(xiàn)定時(shí)去執(zhí)行任務(wù)了
package com.beihui.service.task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class XXXTask {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Scheduled(cron = "0 0 0 * * ?")
public void bTask() {
long startCurrentTime = System.currentTimeMillis();
logger.info("開始執(zhí)行定時(shí)任務(wù):" + startCurrentTime);
//業(yè)務(wù)處理
long endTime = System.currentTimeMillis();
logger.info("定時(shí)任務(wù):執(zhí)行結(jié)束,花費(fèi)時(shí)間" + (endTime - startCurrentTime));
}
@Scheduled(cron = "0 */1 * * * ?")
public void runUpdateDbTask() {
long startCurrentTime = System.currentTimeMillis();
logger.info("開始執(zhí)行更新數(shù)據(jù)庫(kù)剩余次數(shù)定時(shí)任務(wù):" + startCurrentTime);
//業(yè)務(wù)處理
long endTime = System.currentTimeMillis();
logger.info("定時(shí)任務(wù):執(zhí)行結(jié)束,花費(fèi)時(shí)間" + (endTime - startCurrentTime));
}
@Scheduled(fixedDelay = 60 * 1000 * 10)
public void cTask() {
long startCurrentTime = System.currentTimeMillis();
//業(yè)務(wù)處理
long endTime = System.currentTimeMillis();
logger.info("定時(shí)任務(wù):執(zhí)行結(jié)束,花費(fèi)時(shí)間" + (endTime - startCurrentTime));
}
}
但是這個(gè)并不能單次執(zhí)行任務(wù),所以后來 使用listener
代碼如下,并在啟動(dòng)類加上
@ServletComponentScan注解
package xx.xx.xx;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class XXXListener implements ServletContextListener {
private Logger logger = LoggerFactory.getLogger(this.getClass());
//項(xiàng)目啟動(dòng)執(zhí)行
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
long startTime = System.currentTimeMillis();
logger.info("開始執(zhí)行啟動(dòng)任務(wù),{}"+startTime);
//業(yè)務(wù)處理
long endTime = System.currentTimeMillis();
logger.info("執(zhí)行啟動(dòng)任務(wù)結(jié)束,共花費(fèi)時(shí)間{}"+(startTime-endTime));
}
//項(xiàng)目終止時(shí)執(zhí)行
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot整合RocketMQ實(shí)現(xiàn)消息發(fā)送和接收的詳細(xì)步驟
這篇文章主要介紹了SpringBoot整合RocketMQ實(shí)現(xiàn)消息發(fā)送和接收功能,我們使用主流的SpringBoot框架整合RocketMQ來講解,使用方便快捷,本文分步驟給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-08-08
Java設(shè)置Excel數(shù)據(jù)驗(yàn)證的示例代碼
數(shù)據(jù)驗(yàn)證是Excel 2013版本中,數(shù)據(jù)功能組下面的一個(gè)功能。本文將通過Java程序代碼演示數(shù)據(jù)驗(yàn)證的設(shè)置方法及結(jié)果,感興趣的可以了解一下2022-05-05
Java kafka如何實(shí)現(xiàn)自定義分區(qū)類和攔截器
這篇文章主要介紹了Java kafka如何實(shí)現(xiàn)自定義分區(qū)類和攔截器,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
mybatis動(dòng)態(tài)sql之新增與更新方式
這篇文章主要介紹了mybatis動(dòng)態(tài)sql之新增與更新方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
IntelliJ IDEA修改新建文件自動(dòng)生成注釋的user名
今天小編就為大家分享一篇關(guān)于IntelliJ IDEA修改新建文件自動(dòng)生成注釋的user名,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-10-10

