好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

spring-boot 如何实现单次执行程序

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://HdhCmsTestw3.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

查看更多关于spring-boot 如何实现单次执行程序的详细内容...

  阅读:13次