Maven / Vaadin项目中服务器后台如何运行 java class?
How to run java class in back ground of server in Maven / Vaadin project?
问题:
我需要每 24 小时 运行 一个 java 功能。它从一个站点获取一些数据并将该数据推送到数据库。不,我想知道如何在 Tom Cat 服务器上创建 运行 成功的计时器。我有 maven/Vaadin 个项目。所以现在我想知道如何启动定时器功能,该功能将 运行 在服务器上而不是在现场。
白色石英:
计时器:
public class TimerData implements org.quartz.Job {
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
public TimerData() throws SchedulerException, InterruptedException {
sched.scheduleJob(job, trigger);
sched.start();
Thread.sleep(90L * 1000L);
sched.shutdown(true);
}
// define the job and tie it to our HelloJob class
JobDetail job = newJob(TimerData.class)
.withIdentity("job1", "group1")
.build();
// compute a time that is on the next round minute
Date runTime = evenMinuteDate(new Date());
// Trigger the job to run on the next round minute
Trigger trigger = newTrigger()
.withIdentity("trigger1", "group1")
.startAt(runTime)
.build();
// Tell quartz to schedule the job using our trigger
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
// Say Hello to the World and display the date/time
System.out.println("Hello World! - " + new Date());
try {
FillData.povni();
} catch (IOException e) {
e.printStackTrace();
}
}
}
依赖性:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
听众:
public class ContListener implements ServletContextListener,
HttpSessionListener, HttpSessionAttributeListener {
private ServletContext context = null;
// Public constructor is required by servlet spec
public ContListener() {
}
// -------------------------------------------------------
// ServletContextListener implementation
// -------------------------------------------------------
public void contextInitialized(ServletContextEvent sce) {
/* This method is called when the servlet context is
initialized(when the Web application is deployed).
You can initialize servlet context related data here.
*/
context = sce.getServletContext();
}
public void contextDestroyed(ServletContextEvent sce) {
/* This method is invoked when the Servlet Context
(the Web application) is undeployed or
Application Server shuts down.
*/
}
// -------------------------------------------------------
// HttpSessionListener implementation
// -------------------------------------------------------
public void sessionCreated(HttpSessionEvent se) {
/* Session is created. */
}
public void sessionDestroyed(HttpSessionEvent se) {
/* Session is destroyed. */
}
// -------------------------------------------------------
// HttpSessionAttributeListener implementation
// -------------------------------------------------------
public void attributeAdded(HttpSessionBindingEvent sbe) {
/* This method is called when an attribute
is added to a session.
*/
}
public void attributeRemoved(HttpSessionBindingEvent sbe) {
/* This method is called when an attribute
is removed from a session.
*/
}
public void attributeReplaced(HttpSessionBindingEvent sbe) {
/* This method is invoked when an attibute
is replaced in a session.
*/
}
}
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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"
version="3.1">
<context-param>
<param-name>quartz:config-file</param-name>
<param-value>quartz.properties</param-value>
</context-param>
<context-param>
<param-name>quartz:shutdown-on-unload</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>quartz:wait-on-shutdown</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>quartz:start-on-load</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>org.quartz.ee.servlet.QuartzInitializerListener</listener-class>
</listener>
<listener>
<listener-class>ContListener</listener-class>
</listener>
</web-app>
确实,使用 Quartz 是以编程方式执行此操作的最直接方法之一,因为您已经有了 server/app 运行ning.
话虽如此,在任何 Java 网络应用程序中使用它显然独立于您可能使用的 UI 技术(包括 Vaadin)和恕我直言,最好单独进行推理.
为了完整起见,我将在下面详细介绍将 Quartz 添加到 Maven 管理的 Java Web 应用程序所涉及的所有步骤。
将 Quartz 添加为 Maven 依赖项
在您的 pom.xml 中添加一个依赖项就足够了:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.3</version>
</dependency>
在 Servlet 容器中初始化 Quartz 调度器
通过向 web.xml 声明一个 servlet 上下文侦听器和几个上下文参数,在 Servlet 上下文初始化时(如 http://www.quartz-scheduler.org/documentation/quartz-2.x/cookbook/ServletInitScheduler.html 所示)自动创建和初始化默认的 Quartz 调度程序 描述符:
<context-param>
<param-name>quartz:config-file</param-name>
<param-value>/quartz.properties</param-value>
</context-param>
<context-param>
<param-name>quartz:shutdown-on-unload</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>quartz:wait-on-shutdown</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>quartz:start-scheduler-on-load</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>
org.quartz.ee.servlet.QuartzInitializerListener
</listener-class>
</listener>
您还应该通过提供基本的 quartz.properties 文件来配置调度程序:
org.quartz.scheduler.instanceName = LenartScheduler
org.quartz.scheduler.instanceId = LenartScheduler.ID
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
此时,在应用程序 deployed/started 之后,可以从 Web 应用程序的 ServletContext 对象中的默认键下可用的 "standard" 调度程序工厂获取 Quartz 调度程序实例:
StdSchedulerFactory schedFact = (StdSchedulerFactory)
ctx.getAttribute("org.quartz.impl.StdSchedulerFactory.KEY");
try {
Scheduler scheduler = schedFact.getScheduler("LenartScheduler");
// schedule Jobs here...
} catch (SchedulerException e) {
// properly handle the exception...
}
请注意,我们使用了上面 quartz.properties 文件中指定的调度程序名称 (LenartScheduler)。另外,请注意,此时还没有任何计划——我们所拥有的只是一个可以使用的计划程序。
创建作业Class
通过实施 org.quartz.Job:
轻松完成
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class MainJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext)
throws JobExecutionException {
// Simulate job execution for 5 seconds...
try {
System.out.println("Executing job in background...");
Thread.sleep(1000 * 5 /* secs */);
System.out.println("Done executing job.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
正在安排作业[=105=]
给定可用的调度器,我们需要定义:
- 所谓"details"一个Job
AND
- 这些细节的触发器
并使用它们来最终安排作业:
private void scheduleMainJob(Scheduler scheduler) throws SchedulerException {
requireNonNull(scheduler);
JobDetail jobDetail = newJob(MainJob.class).storeDurably()
.withIdentity("MAIN_JOB")
.withDescription("Main Job to Perform")
.build();
Trigger trigger = newTrigger().forJob(jobDetail)
.withIdentity("MAIN_JOB_TRIGG")
.withDescription("Trigger for Main Job")
.withSchedule(simpleSchedule().withIntervalInSeconds(15).repeatForever())
.startNow().build();
scheduler.scheduleJob(jobDetail, trigger);
}
注意指定何时触发作业的简单方法(没有 cron 表达式涉及您的简单案例,至少现在还没有)。为了这个例子,我每 15 秒触发一次作业,并让它 运行 持续 5 次——如果你想每 24 小时触发一次(即每天一次),你可以使用 simpleSchedule().withIntervalInHours(24).repeatForever().
自动安排作业[=105=]
现在,精明的人会注意到我们还没有调用调度功能。我们可以通过定义某种管理员 servlet/UI 并在用户交互时调用上面定义的调度方法,或者,如果我们可以使用 predefined/hardcoded 值, 自动 ,在 servlet 上下文启动时,就像我们使用调度程序完成。
假设我们想要在 servlet 上下文启动时自动安排主作业。我们又至少有 2 个选项:
- 实现一个 ServletContextListener,does/calls 上面的调度例程,并确保在我们声明的 QuartzInitializerListener 之后调用它,以便创建调度程序
或
扩展 QuartzInitializerListener class 以在调度程序创建后立即调度我们的主要工作;这样,我们就不必担心调用上下文侦听器的顺序:
public class LenartQuartzListener extends QuartzInitializerListener {
@Override
public void contextInitialized(ServletContextEvent evt) {
super.contextInitialized(evt);
// At this point, the default functionality
// has been executed hence the scheduler has been created!
ServletContext ctx = evt.getServletContext();
StdSchedulerFactory factory = (StdSchedulerFactory)
ctx.getAttribute("org.quartz.impl.StdSchedulerFactory.KEY");
try {
scheduleMainJob(factory.getScheduler("LenartScheduler"));
} catch (SchedulerException e) {
// properly handle the exception...
}
}
}
但是,如果我们使用(更好的,恕我直言)第二个选项,我们确实需要在 web.xml 文件中指定我们新的 Quartz 侦听器,而不是如果旧的:
<listener>
<listener-class>com.lenard.web.LenartQuartzListener</listener-class>
</listener>
此时,不用担心使用的 UI 技术(Vaadin 等),Quartz 调度程序会自动初始化并在(网络)应用程序启动时安排作业。
如果使用 Vaadin
如今,无需使用 web.xml 描述符即可初始化基于 Vaadin 的 Web 应用程序。如果是这种情况,请注意您现在需要添加 web.xml 文件来指定我们一直在讨论的 Quartz 初始化。但这并不与任何 Vaadin 特定的东西冲突......
我在 https://github.com/octavian-nita/so/tree/master/so-42899401-quartz-maven-tomcat 创建了一个基于 Vaadin 的小项目来说明如何使用 Vaadin UI 手动安排/取消安排 Quartz 作业。欢迎研究并提前提问!
为此创建了一个虚拟样板项目。
看看https://github.com/dhruvpsaru/quartz-test
代替xml我使用我认为更好的注释
pom.xml 是
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>web-app</groupId>
<artifactId>app</artifactId>
<packaging>war</packaging>
<version>1.0</version>
<name>app Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.7</version>
</dependency>
</dependencies>
<build>
<finalName>app</finalName>
</build>
</project>
创建一个 servlet 作为
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;
import java.io.PrintWriter;
@WebServlet(
name = "AnnotatedServlet",
description = "A sample annotated servlet",
urlPatterns = {"/test"}
)
public class AppServlet extends HttpServlet {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
logger.info("------------------------in servlet-------------------");
PrintWriter writer = resp.getWriter();
writer.println("<html>Hello, I am a Java servlet!</html>");
writer.flush();
}
}
创建工作 class 作为
package quartz;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SimpleJob implements Job {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
logger.info("This is my first quartz job!!");
}
}
并创建一个侦听器为
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import static org.quartz.TriggerBuilder.newTrigger;
@WebListener
public class QuartzScheduler implements ServletContextListener {
private Scheduler scheduler = null;
private final Logger logger = LoggerFactory.getLogger(this.getClass());
public void contextInitialized(ServletContextEvent servletContextEvent) {
logger.info("Context Initialized");
try {
// Setup the Job class and the Job group
JobDetail job = JobBuilder.newJob(SimpleJob.class).withIdentity(
"CronQuartzJob", "Group").build();
// Create a Trigger that fires every 5 minutes.
Trigger trigger = newTrigger()
.withIdentity("TriggerName", "Group")
.withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
.build();
// Setup the Job and Trigger with Scheduler & schedule jobs
scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
public void contextDestroyed(ServletContextEvent servletContextEvent) {
logger.info("Context Destroyed");
try
{
scheduler.shutdown();
}
catch (SchedulerException e)
{
e.printStackTrace();
}
}
}
现在去做 mvn clean package
并部署 target/app.war
问题: 我需要每 24 小时 运行 一个 java 功能。它从一个站点获取一些数据并将该数据推送到数据库。不,我想知道如何在 Tom Cat 服务器上创建 运行 成功的计时器。我有 maven/Vaadin 个项目。所以现在我想知道如何启动定时器功能,该功能将 运行 在服务器上而不是在现场。
白色石英:
计时器:
public class TimerData implements org.quartz.Job {
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
public TimerData() throws SchedulerException, InterruptedException {
sched.scheduleJob(job, trigger);
sched.start();
Thread.sleep(90L * 1000L);
sched.shutdown(true);
}
// define the job and tie it to our HelloJob class
JobDetail job = newJob(TimerData.class)
.withIdentity("job1", "group1")
.build();
// compute a time that is on the next round minute
Date runTime = evenMinuteDate(new Date());
// Trigger the job to run on the next round minute
Trigger trigger = newTrigger()
.withIdentity("trigger1", "group1")
.startAt(runTime)
.build();
// Tell quartz to schedule the job using our trigger
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
// Say Hello to the World and display the date/time
System.out.println("Hello World! - " + new Date());
try {
FillData.povni();
} catch (IOException e) {
e.printStackTrace();
}
}
}
依赖性:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
听众:
public class ContListener implements ServletContextListener,
HttpSessionListener, HttpSessionAttributeListener {
private ServletContext context = null;
// Public constructor is required by servlet spec
public ContListener() {
}
// -------------------------------------------------------
// ServletContextListener implementation
// -------------------------------------------------------
public void contextInitialized(ServletContextEvent sce) {
/* This method is called when the servlet context is
initialized(when the Web application is deployed).
You can initialize servlet context related data here.
*/
context = sce.getServletContext();
}
public void contextDestroyed(ServletContextEvent sce) {
/* This method is invoked when the Servlet Context
(the Web application) is undeployed or
Application Server shuts down.
*/
}
// -------------------------------------------------------
// HttpSessionListener implementation
// -------------------------------------------------------
public void sessionCreated(HttpSessionEvent se) {
/* Session is created. */
}
public void sessionDestroyed(HttpSessionEvent se) {
/* Session is destroyed. */
}
// -------------------------------------------------------
// HttpSessionAttributeListener implementation
// -------------------------------------------------------
public void attributeAdded(HttpSessionBindingEvent sbe) {
/* This method is called when an attribute
is added to a session.
*/
}
public void attributeRemoved(HttpSessionBindingEvent sbe) {
/* This method is called when an attribute
is removed from a session.
*/
}
public void attributeReplaced(HttpSessionBindingEvent sbe) {
/* This method is invoked when an attibute
is replaced in a session.
*/
}
}
Web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app 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"
version="3.1">
<context-param>
<param-name>quartz:config-file</param-name>
<param-value>quartz.properties</param-value>
</context-param>
<context-param>
<param-name>quartz:shutdown-on-unload</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>quartz:wait-on-shutdown</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>quartz:start-on-load</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>org.quartz.ee.servlet.QuartzInitializerListener</listener-class>
</listener>
<listener>
<listener-class>ContListener</listener-class>
</listener>
</web-app>
确实,使用 Quartz 是以编程方式执行此操作的最直接方法之一,因为您已经有了 server/app 运行ning.
话虽如此,在任何 Java 网络应用程序中使用它显然独立于您可能使用的 UI 技术(包括 Vaadin)和恕我直言,最好单独进行推理.
为了完整起见,我将在下面详细介绍将 Quartz 添加到 Maven 管理的 Java Web 应用程序所涉及的所有步骤。
将 Quartz 添加为 Maven 依赖项
在您的 pom.xml 中添加一个依赖项就足够了:
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.3</version>
</dependency>
在 Servlet 容器中初始化 Quartz 调度器
通过向 web.xml 声明一个 servlet 上下文侦听器和几个上下文参数,在 Servlet 上下文初始化时(如 http://www.quartz-scheduler.org/documentation/quartz-2.x/cookbook/ServletInitScheduler.html 所示)自动创建和初始化默认的 Quartz 调度程序 描述符:
<context-param>
<param-name>quartz:config-file</param-name>
<param-value>/quartz.properties</param-value>
</context-param>
<context-param>
<param-name>quartz:shutdown-on-unload</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>quartz:wait-on-shutdown</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>quartz:start-scheduler-on-load</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>
org.quartz.ee.servlet.QuartzInitializerListener
</listener-class>
</listener>
您还应该通过提供基本的 quartz.properties 文件来配置调度程序:
org.quartz.scheduler.instanceName = LenartScheduler
org.quartz.scheduler.instanceId = LenartScheduler.ID
org.quartz.threadPool.threadCount = 3
org.quartz.jobStore.class = org.quartz.simpl.RAMJobStore
此时,在应用程序 deployed/started 之后,可以从 Web 应用程序的 ServletContext 对象中的默认键下可用的 "standard" 调度程序工厂获取 Quartz 调度程序实例:
StdSchedulerFactory schedFact = (StdSchedulerFactory)
ctx.getAttribute("org.quartz.impl.StdSchedulerFactory.KEY");
try {
Scheduler scheduler = schedFact.getScheduler("LenartScheduler");
// schedule Jobs here...
} catch (SchedulerException e) {
// properly handle the exception...
}
请注意,我们使用了上面 quartz.properties 文件中指定的调度程序名称 (LenartScheduler)。另外,请注意,此时还没有任何计划——我们所拥有的只是一个可以使用的计划程序。
创建作业Class
通过实施 org.quartz.Job:
轻松完成import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class MainJob implements Job {
@Override
public void execute(JobExecutionContext jobExecutionContext)
throws JobExecutionException {
// Simulate job execution for 5 seconds...
try {
System.out.println("Executing job in background...");
Thread.sleep(1000 * 5 /* secs */);
System.out.println("Done executing job.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
正在安排作业[=105=]
给定可用的调度器,我们需要定义:
- 所谓"details"一个Job
AND
- 这些细节的触发器
并使用它们来最终安排作业:
private void scheduleMainJob(Scheduler scheduler) throws SchedulerException {
requireNonNull(scheduler);
JobDetail jobDetail = newJob(MainJob.class).storeDurably()
.withIdentity("MAIN_JOB")
.withDescription("Main Job to Perform")
.build();
Trigger trigger = newTrigger().forJob(jobDetail)
.withIdentity("MAIN_JOB_TRIGG")
.withDescription("Trigger for Main Job")
.withSchedule(simpleSchedule().withIntervalInSeconds(15).repeatForever())
.startNow().build();
scheduler.scheduleJob(jobDetail, trigger);
}
注意指定何时触发作业的简单方法(没有 cron 表达式涉及您的简单案例,至少现在还没有)。为了这个例子,我每 15 秒触发一次作业,并让它 运行 持续 5 次——如果你想每 24 小时触发一次(即每天一次),你可以使用 simpleSchedule().withIntervalInHours(24).repeatForever().
自动安排作业[=105=]
现在,精明的人会注意到我们还没有调用调度功能。我们可以通过定义某种管理员 servlet/UI 并在用户交互时调用上面定义的调度方法,或者,如果我们可以使用 predefined/hardcoded 值, 自动 ,在 servlet 上下文启动时,就像我们使用调度程序完成。
假设我们想要在 servlet 上下文启动时自动安排主作业。我们又至少有 2 个选项:
- 实现一个 ServletContextListener,does/calls 上面的调度例程,并确保在我们声明的 QuartzInitializerListener 之后调用它,以便创建调度程序
或
扩展 QuartzInitializerListener class 以在调度程序创建后立即调度我们的主要工作;这样,我们就不必担心调用上下文侦听器的顺序:
public class LenartQuartzListener extends QuartzInitializerListener { @Override public void contextInitialized(ServletContextEvent evt) { super.contextInitialized(evt); // At this point, the default functionality // has been executed hence the scheduler has been created! ServletContext ctx = evt.getServletContext(); StdSchedulerFactory factory = (StdSchedulerFactory) ctx.getAttribute("org.quartz.impl.StdSchedulerFactory.KEY"); try { scheduleMainJob(factory.getScheduler("LenartScheduler")); } catch (SchedulerException e) { // properly handle the exception... } } }
但是,如果我们使用(更好的,恕我直言)第二个选项,我们确实需要在 web.xml 文件中指定我们新的 Quartz 侦听器,而不是如果旧的:
<listener>
<listener-class>com.lenard.web.LenartQuartzListener</listener-class>
</listener>
此时,不用担心使用的 UI 技术(Vaadin 等),Quartz 调度程序会自动初始化并在(网络)应用程序启动时安排作业。
如果使用 Vaadin
如今,无需使用 web.xml 描述符即可初始化基于 Vaadin 的 Web 应用程序。如果是这种情况,请注意您现在需要添加 web.xml 文件来指定我们一直在讨论的 Quartz 初始化。但这并不与任何 Vaadin 特定的东西冲突......
我在 https://github.com/octavian-nita/so/tree/master/so-42899401-quartz-maven-tomcat 创建了一个基于 Vaadin 的小项目来说明如何使用 Vaadin UI 手动安排/取消安排 Quartz 作业。欢迎研究并提前提问!
为此创建了一个虚拟样板项目。 看看https://github.com/dhruvpsaru/quartz-test
代替xml我使用我认为更好的注释
pom.xml 是
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>web-app</groupId>
<artifactId>app</artifactId>
<packaging>war</packaging>
<version>1.0</version>
<name>app Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.7</version>
</dependency>
</dependencies>
<build>
<finalName>app</finalName>
</build>
</project>
创建一个 servlet 作为
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;
import java.io.PrintWriter;
@WebServlet(
name = "AnnotatedServlet",
description = "A sample annotated servlet",
urlPatterns = {"/test"}
)
public class AppServlet extends HttpServlet {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
logger.info("------------------------in servlet-------------------");
PrintWriter writer = resp.getWriter();
writer.println("<html>Hello, I am a Java servlet!</html>");
writer.flush();
}
}
创建工作 class 作为
package quartz;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SimpleJob implements Job {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
logger.info("This is my first quartz job!!");
}
}
并创建一个侦听器为
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import static org.quartz.TriggerBuilder.newTrigger;
@WebListener
public class QuartzScheduler implements ServletContextListener {
private Scheduler scheduler = null;
private final Logger logger = LoggerFactory.getLogger(this.getClass());
public void contextInitialized(ServletContextEvent servletContextEvent) {
logger.info("Context Initialized");
try {
// Setup the Job class and the Job group
JobDetail job = JobBuilder.newJob(SimpleJob.class).withIdentity(
"CronQuartzJob", "Group").build();
// Create a Trigger that fires every 5 minutes.
Trigger trigger = newTrigger()
.withIdentity("TriggerName", "Group")
.withSchedule(CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
.build();
// Setup the Job and Trigger with Scheduler & schedule jobs
scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
scheduler.scheduleJob(job, trigger);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
public void contextDestroyed(ServletContextEvent servletContextEvent) {
logger.info("Context Destroyed");
try
{
scheduler.shutdown();
}
catch (SchedulerException e)
{
e.printStackTrace();
}
}
}
现在去做 mvn clean package
并部署 target/app.war