纯java实现tomcat下的定时任务
Easul Lv6

这里需要先创建一个简单的javaweb项目,可以参考这里

项目结构

1
2
3
4
5
6
7
8
9
10
11
12
projectName    项目名称
├── ml
│ └── lightly
│ └── demo 包源码目录结构
│ ├── bean
│ │ └── ScheduleBean.java 实体类文件
│ └── listener
│ └── ScheduleListener.java 监听器文件
└── WEB-INF
├── classes 放java文件的包和类
│ └── api.properties 配置文件
└── web.xml 进行javaweb的一些配置

api.properties

用于指定执行的时间间隔

PROPERTIES
1
executionInterval=30

项目中web.xml的设置

只需要放一个监听器的设置即可,servlet默认首页的设置不用放

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1"
metadata-complete="true"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<listener>
<!--放监听器的类-->
<listener-class>
ml.lightly.demo.listener.ScheduleListener
</listener-class>
</listener>
</web-app>

监听器

导入tomcat目录/lib/servlet-api.jar即可

  • ScheduleListener

    JAVA
    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
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    package ml.lightly.demo.listener;

    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Properties;
    import java.util.Timer;// 定时器类
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;

    import ml.lightly.demo.bean.ScheduleBean;

    // 做监听器需要实现这个类
    public class ScheduleListener implements ServletContextListener {
    private Timer timer = null;

    /**
    * 初始化监听器方法,tomcat启动时监听。在这里添加定时器功能
    */
    public void contextInitialized(ServletContextEvent event) {
    // 获取定时任务执行毫秒数
    int executionInterval = getExecutionInterval();
    // 创建定时器
    timer = new Timer(true);
    // 添加日志,日志存储到tomcat的日志中
    event.getServletContext().log("任务开始");

    // 参数1:传入定时任务,
    // 参数2:0表示第一次执行任务时无延迟,
    // 参数3:间隔EXECUTION_INTERVAL毫秒再次执行任务
    timer.schedule(new ScheduleBean(event.getServletContext()), 0, executionInterval);
    event.getServletContext().log("任务添加");
    }

    /**
    * 监听器销毁方法。在这里销毁定时器
    */
    public void contextDestroyed(ServletContextEvent event) {
    timer.cancel();
    event.getServletContext().log("任务销毁");
    }

    /**
    * 获取配置文件中定时任务执行毫秒数
    */
    private static int getExecutionInterval() {
    // 读取配置文件信息
    Properties properties = new Properties();
    // 使用当前类加载器获取文件流
    InputStream inputStream = ScheduleListener.class.getClassLoader().getResourceAsStream("api.properties");
    int executionInterval = 0;
    try {
    properties.load(inputStream);
    executionInterval = Integer.parseInt(properties.get("executionInterval").toString()) * 1000;
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    try {
    inputStream.close();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    return executionInterval;
    }
    }
  • ScheduleBean

    JAVA
    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
    39
    40
    41
    42
    43
    package ml.lightly.demo.bean;

    import java.util.Calendar;
    import java.util.TimerTask;
    import javax.servlet.ServletContext;

    /**
    * 定时器任务需要继承自TimerTask
    */
    public class ScheduleBean extends TimerTask {

    private static final int C_SCHEDULE_HOUR = 0; // 定义执行时间
    private static boolean isRunning = false; // 用于只让一个任务运行
    private ServletContext context = null; // 用于日志的记录

    // 将记录日志对象传进来
    public ScheduleBean(ServletContext context) {
    this.context = context;
    }

    public void run() {
    Calendar c = Calendar.getInstance();
    // 有一个对象执行,isRunning为true,其他对象则不能执行
    if(!isRunning) {
    // 判断当前时间是否是定义的执行时间
    if(C_SCHEDULE_HOUR == c.get(Calendar.HOUR_OF_DAY)) {
    // 避免新对象进行任务执行。
    isRunning = true;
    context.log("开始执行指定任务");
    // -------------------开始保存当日历史记录
    // 在这里编写自己的功能,例:
    // File file = new File("temp");
    // file.mkdir();
    // 启动tomcat,可以发现在tomcat根目录下,会自动创建temp文件夹
    // -------------------结束
    isRunning = false;
    context.log("指定任务执行结束");
    } else {
    context.log("上一次任务执行还未结束");
    }
    }
    }
    }

java命令行编译

BASH
1
2
3
4
5
# cp后边指定依赖jar包的路径,windows的路径使用\隔开,linux的路径使用/隔开
# 如果有多个jar包,windows用;隔开,linux用:隔开
# -encoding 指定编码的字符集
# -d 指定输出的目录
javac -encoding utf-8 -cp /home/easul/software/apache-tomcat-9.0.59/lib/servlet-api.jar -d /home/easul/work/spring-boot-project/demo/test2/WEB-INF/classes ./ml/lightly/demo/bean/ScheduleBean.java ./ml/lightly/demo/listener/ScheduleListener.java

运行

projectName整个文件夹复制到tomcat/webapps
projectName下的ml/lightly/demo这整个文件夹就没用了,里边放的是源码,不运行源码,所以可以不复制
tomcat/bin下运行如下命令

BASH
1
2
3
./catalina.sh run
# 使用tail查看日志
tail -f tomcat目录/logs/localhost.`date +%Y-%m-%d`.log

参考

 评论