spring-boot 單次執行程序
spring-boot做為spring的集大成框架,大部分時候作為WEB服務被集成使用,但某些情況下,需要手動執行一些邏輯的情況下,單次運行的類似腳本的程序也是很有用的。
本文記錄一下使用spring-boot作為單次可執行程序配置方式。
pom.xml
注意:pom.xml部分只需引入spring-boot-starter模塊,尤其不要引入web模塊,其他非spring本身模塊可以隨意引入
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
<? 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 > <!-- 按工程習慣處理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 > |
主要代碼結構
Service類
1
2
3
4
5
6
|
@Service public class StatService { public void doSomething() { System.out.println( "===================: this is a test service but nothing" ); } } |
執行邏輯入口類
1
2
3
4
5
6
7
8
9
10
11
|
@Component public class StatTask { private StatService statService; @Autowired public StatTask(StatService statService) { this .statService = statService; } public void doSomething() { statService.doSomething(); } } |
Spring-boot 啟動類
1
2
3
4
5
6
7
8
|
@SpringBootApplication public class TaskApplication { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(TaskApplication. class , args); StatTask statTask = context.getBean(StatTask. class ); // 獲取邏輯入口類的實例 statTask.doSomething(); } } |
如此這般后,啟動這個springboot工程,執行完啟動類中的調用過程后,程序就會自動退出。
基本上,不配置啟用spring mvc和定時Job,這種配置下的springboot就是一個“腳本”程序。
這里舉個?,上面的代碼加上兩個注解,就會變成常駐進程程序:
執行邏輯入口類
1
2
3
4
5
6
7
8
9
10
11
12
13
|
@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 啟動類
1
2
3
4
5
6
7
8
9
|
@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(); } } |
與最上面區別的是,上面只執行一次,輸出 “this is a test service but nothing” 就完事了,進程自動退出,
加上兩個注解后就會每5秒輸出一次 “this is a test service but nothing”,且進程永駐。
當然這種情況下使用腳本語言如python、nodeJs等可能更好一些,但在其他語言不熟的情況下,使用spring-boot來應急也是極好的。
啟動時執行單次任務
最近做任務遇到一個問題,需要在項目啟動時候執行掃描數據庫表的任務,用于異?;謴腿轂?,一開始想的是可不可以使用定時任務
代碼如下 并且在啟動類加上
@EnableScheduling注解就可以實現定時去執行任務了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
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( "開始執行定時任務:" + startCurrentTime); //業務處理 long endTime = System.currentTimeMillis(); logger.info( "定時任務:執行結束,花費時間" + (endTime - startCurrentTime)); } @Scheduled (cron = "0 */1 * * * ?" ) public void runUpdateDbTask() { long startCurrentTime = System.currentTimeMillis(); logger.info( "開始執行更新數據庫剩余次數定時任務:" + startCurrentTime); //業務處理 long endTime = System.currentTimeMillis(); logger.info( "定時任務:執行結束,花費時間" + (endTime - startCurrentTime)); } @Scheduled (fixedDelay = 60 * 1000 * 10 ) public void cTask() { long startCurrentTime = System.currentTimeMillis(); //業務處理 long endTime = System.currentTimeMillis(); logger.info( "定時任務:執行結束,花費時間" + (endTime - startCurrentTime)); } } |
但是這個并不能單次執行任務,所以后來 使用listener
代碼如下,并在啟動類加上
@ServletComponentScan注解
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
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()); //項目啟動執行 @Override public void contextInitialized(ServletContextEvent servletContextEvent) { long startTime = System.currentTimeMillis(); logger.info( "開始執行啟動任務,{}" +startTime); //業務處理 long endTime = System.currentTimeMillis(); logger.info( "執行啟動任務結束,共花費時間{}" +(startTime-endTime)); } //項目終止時執行 @Override public void contextDestroyed(ServletContextEvent servletContextEvent) { } } |
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/zombres/article/details/88670899