定时任务

EJB提供了一个简单易用的定时调度功能,它支持声明式的创建定时任务,可以用于周期性执行后台业务逻辑,例如关闭订单、报表生成、异步通知等。这篇笔记我们简单了解EJB中定时任务的编写。

@Schedule声明定时任务

下面例子中我们基于单例会话Bean实现了一个定时任务,它每隔3秒执行一次,打印一条日志信息。

package com.gacfox.netstore.ejb;

import org.jboss.logging.Logger;

import javax.ejb.Schedule;
import javax.ejb.Singleton;

@Singleton
public class StatisticsService {
    private static final Logger logger = Logger.getLogger(StatisticsService.class);

    @Schedule(second = "*/3", minute = "*", hour = "*")
    public void statistics() {
        logger.info("Statistics service invoked");
    }
}

代码中,我们使用@Schedule注解标注了一个方法,被标注的方法将被自动调度执行,这种定时器也被称为日历定时器(Calendar Timer)。@Schedule支持很多配置参数,我们可以组合这些参数实现灵活的定时任务配置。

  • second、minute、hour、dayOfMonth、month、dayOfWeek、year:这些属性用于指定定时任务的执行时间,可以使用具体值表达在对应时间点执行,也可以使用类似**/3的写法表示每时间单位执行、每3次时间单位执行。
  • persistent:指示定时任务是否持久化,默认值是true,即任务会在服务器重启后恢复

TimerService创建定时任务

TimerService是EJB维护的一个核心调度器,和@Schedule声明式定时任务不同,使用TimerService我们可以使用Java代码动态的注册或取消定时任务。

下面例子代码中,我们在一个EJB实现类里使用@Resource注入了TimerService,当EJB的beginScheduledTask()方法被调用时,我们启动了一个固定间隔执行的定时任务,当stopScheduledTask()方法被调用时定时任务取消。定时任务触发时,标注@Timeout的方法将被定时执行。

package com.gacfox.netstore.ejb;

import com.gacfox.netstore.api.StatisticsService;
import org.jboss.logging.Logger;

import javax.annotation.Resource;
import javax.ejb.*;

@Singleton
public class StatisticsServiceImpl implements StatisticsService {
    @Resource
    private TimerService timerService;

    private static final Logger logger = Logger.getLogger(StatisticsServiceImpl.class);
    private Timer timer = null;

    @Timeout
    public void statistics(Timer timer) {
        logger.info("Statistics service invoked");
    }

    @Override
    public void beginScheduledTask() {
        if (timer == null) {
            timer = timerService.createIntervalTimer(0, 1000, new TimerConfig("statisticsTask", true));
        }
    }

    @Override
    public void stopScheduledTask() {
        if (timer != null) {
            timer.cancel();
        }
    }
}

下面的Servlet作为EJB的客户端,动态的控制着定时任务的注册和取消。

package com.gacfox.netstore.web.servlet;

import com.gacfox.netstore.api.StatisticsService;

import javax.ejb.EJB;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(name = "StatisticsTaskServlet", urlPatterns = "/task")
public class StatisticsTaskServlet extends HttpServlet {
    @EJB
    private StatisticsService statisticsService;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String action = req.getParameter("action");
        if ("start".equals(action)) {
            statisticsService.beginScheduledTask();
        } else if ("stop".equals(action)) {
            statisticsService.stopScheduledTask();
        }
    }
}
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap