applicationContext.xml 调用 CronTriggerScheduler 但应用程序未安排
applicationContext.xml calls the CronTriggerScheduler but application isn't scheduled
我正在使用 IntelliJ Idea 并使用 Tomcat 作为本地服务器。
我尝试在 5 秒内将数据插入 MySQL 数据库。我在 applicationContext.xml 文件中使用 Cron Trigger 安排应用程序。
在 applicationContext.xml 文件中,我将 dummycode 作为调用 CurrencyAddJob.java 的 cron 触发器,已经安排了我的 class。但是,当我创建一个名为 CronTriggerScheduler.java 和 运行 的新 java class 应用程序时,应用程序未安排。
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<context:component-scan base-package="com.honorius.billing.*">
</context:component-scan>
<context:property-placeholder location="classpath:com"/>
<bean id="honoriusDataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://url adress here"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
<property name="jmxEnabled" value="true"/>
<property name="initialSize" value="10"/>
<property name="maxActive" value="2000"/>
<property name="maxIdle" value="500"/>
<property name="minIdle" value="10"/>
<property name="suspectTimeout" value="60"/>
<property name="timeBetweenEvictionRunsMillis" value="30000"/>
<property name="minEvictableIdleTimeMillis" value="60000"/>
<property name="validationQuery" value="select 1 from dual;"/>
<property name="testOnConnect" value="true"/>
<property name="testWhileIdle" value="true"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="honoriusDataSource"/>
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="applicationContextSchedulerContextKey" value="applicationContext"/>
<property name="overwriteExistingJobs" value="true"/>
<property name="jobDetails">
<list>
<ref bean="dailyCountJob"/>
</list>
</property>
<property name="triggers">
<list>
<ref bean="dailyCountJobCronTrigger"/>
</list>
</property>
</bean>
<bean id="mySched" class="com.honorius.billing.CronTriggerScheduler" init-method="init"></bean>
</beans>
CurrencyAddJob.java:
package com.honorius.billing.job;
import com.honorius.billing.dao.impl.CurrenciesDao;
import com.honorius.billing.service.AsynchronousRunnerService;
import com.honorius.billing.service.task.AddCurrencyTask;
import com.honorius.billing.dao.model.Currencies;
import com.honorius.billing.service.CurrencyService;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerException;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class CurrencyAddJob extends QuartzJobBean {
private transient CurrenciesDao currenciesDao;
private transient CurrencyService currencyService;
private transient AsynchronousRunnerService asynchronousRunnerService;
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext)
throws JobExecutionException {
// spring quartz initializes from applicationContext
ApplicationContext applicationContext = null;
try {
applicationContext = (ApplicationContext) jobExecutionContext
.getScheduler().getContext().get("applicationContext");
} catch (SchedulerException e1) {
e1.printStackTrace();
}
if (applicationContext != null) {
currenciesDao = applicationContext.getBean(CurrenciesDao.class);
}
//if (currencyService == null) {
// currencyService = (CurrencyService) applicationContext.getBean("currencyService");
//}
if (currenciesDao == null) {
currenciesDao = (CurrenciesDao) jobExecutionContext.getJobDetail()
.getJobDataMap().get("CurrenciesDao");
}
if (asynchronousRunnerService == null) {
assert applicationContext != null;
asynchronousRunnerService = (AsynchronousRunnerService) applicationContext.getBean("asynchronousRunnerService");
}
//// TODO: INSERT TO CURRENCY TABLE
Currencies curr = new Currencies();
//curr.setId(Long.valueOf(10));
curr.setId(null);
curr.setIso("Suc");
curr.setName("Honorius");
asynchronousRunnerService.runAsynchronously(new AddCurrencyTask(currenciesDao, curr));
}
}
web.xml:
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>Honorius Batch Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
它运行完美,每 5 秒就有一个新数据插入 CurrencyTable。但是,当更新 applicationContext.xml 并创建 CronTriggerSchedler.java 时,CurrencyAddJob.java 中的 applicationContext 和 asynchronousRunnerService 变量将在调试模式下变为 "null"。调用 CurrecnyAddJob.java 后应用程序卡在循环中。
已更新applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<context:component-scan base-package="com.honorius.billing.*">
</context:component-scan>
<context:property-placeholder location="classpath:com"/>
<bean id="honoriusDataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://url address here"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
<property name="jmxEnabled" value="true"/>
<property name="initialSize" value="10"/>
<property name="maxActive" value="2000"/>
<property name="maxIdle" value="500"/>
<property name="minIdle" value="10"/>
<property name="suspectTimeout" value="60"/>
<property name="timeBetweenEvictionRunsMillis" value="30000"/>
<property name="minEvictableIdleTimeMillis" value="60000"/>
<property name="validationQuery" value="select 1 from dual;"/>
<property name="testOnConnect" value="true"/>
<property name="testWhileIdle" value="true"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="honoriusDataSource"/>
</bean>
<bean id="mySched" class="com.honorius.billing.CronTriggerScheduler" init-method="init"></bean>
</beans>
CronTriggerScheduler.java:
public class CronTriggerScheduler {
public void init(){
scheduler();
}
public static void scheduler(){
try {
Scheduler scheduler;
scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
JobDetail job = JobBuilder.newJob(CurrencyAddJob.class)
.withIdentity("DailyJobs", "group").build();
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("dailyJobCronTrigger", "group")
.withSchedule(
CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
.build();
scheduler.scheduleJob(job, trigger);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
如何使用 CronTriggerScheduler.java 安排我的应用程序。
任何帮助将不胜感激。
要使依赖注入在您的作业 bean (CurrencyAddJob) 上工作,调度程序必须由 Spring 创建。将 SchedulerFactoryBean 保留在 xml 中,但没有任何作业或触发器。
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="applicationContextSchedulerContextKey" value="applicationContext"/>
</bean>
然后注入CronTriggerScheduler
public class CronTriggerScheduler {
@Autowired
private Scheduler scheduler;
public void init(){
scheduleJob();
}
private void scheduleJob() {
try {
JobDetail job = JobBuilder.newJob(CurrencyAddJob.class)
.withIdentity("DailyJobs", "group").build();
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("dailyJobCronTrigger", "group")
.withSchedule(
CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
.build();
scheduler.scheduleJob(job, trigger);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
注意:无需将创建作业的方法设为静态 public。
我正在使用 IntelliJ Idea 并使用 Tomcat 作为本地服务器。 我尝试在 5 秒内将数据插入 MySQL 数据库。我在 applicationContext.xml 文件中使用 Cron Trigger 安排应用程序。
在 applicationContext.xml 文件中,我将 dummycode 作为调用 CurrencyAddJob.java 的 cron 触发器,已经安排了我的 class。但是,当我创建一个名为 CronTriggerScheduler.java 和 运行 的新 java class 应用程序时,应用程序未安排。
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<context:component-scan base-package="com.honorius.billing.*">
</context:component-scan>
<context:property-placeholder location="classpath:com"/>
<bean id="honoriusDataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://url adress here"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
<property name="jmxEnabled" value="true"/>
<property name="initialSize" value="10"/>
<property name="maxActive" value="2000"/>
<property name="maxIdle" value="500"/>
<property name="minIdle" value="10"/>
<property name="suspectTimeout" value="60"/>
<property name="timeBetweenEvictionRunsMillis" value="30000"/>
<property name="minEvictableIdleTimeMillis" value="60000"/>
<property name="validationQuery" value="select 1 from dual;"/>
<property name="testOnConnect" value="true"/>
<property name="testWhileIdle" value="true"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="honoriusDataSource"/>
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="applicationContextSchedulerContextKey" value="applicationContext"/>
<property name="overwriteExistingJobs" value="true"/>
<property name="jobDetails">
<list>
<ref bean="dailyCountJob"/>
</list>
</property>
<property name="triggers">
<list>
<ref bean="dailyCountJobCronTrigger"/>
</list>
</property>
</bean>
<bean id="mySched" class="com.honorius.billing.CronTriggerScheduler" init-method="init"></bean>
</beans>
CurrencyAddJob.java:
package com.honorius.billing.job;
import com.honorius.billing.dao.impl.CurrenciesDao;
import com.honorius.billing.service.AsynchronousRunnerService;
import com.honorius.billing.service.task.AddCurrencyTask;
import com.honorius.billing.dao.model.Currencies;
import com.honorius.billing.service.CurrencyService;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.SchedulerException;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class CurrencyAddJob extends QuartzJobBean {
private transient CurrenciesDao currenciesDao;
private transient CurrencyService currencyService;
private transient AsynchronousRunnerService asynchronousRunnerService;
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext)
throws JobExecutionException {
// spring quartz initializes from applicationContext
ApplicationContext applicationContext = null;
try {
applicationContext = (ApplicationContext) jobExecutionContext
.getScheduler().getContext().get("applicationContext");
} catch (SchedulerException e1) {
e1.printStackTrace();
}
if (applicationContext != null) {
currenciesDao = applicationContext.getBean(CurrenciesDao.class);
}
//if (currencyService == null) {
// currencyService = (CurrencyService) applicationContext.getBean("currencyService");
//}
if (currenciesDao == null) {
currenciesDao = (CurrenciesDao) jobExecutionContext.getJobDetail()
.getJobDataMap().get("CurrenciesDao");
}
if (asynchronousRunnerService == null) {
assert applicationContext != null;
asynchronousRunnerService = (AsynchronousRunnerService) applicationContext.getBean("asynchronousRunnerService");
}
//// TODO: INSERT TO CURRENCY TABLE
Currencies curr = new Currencies();
//curr.setId(Long.valueOf(10));
curr.setId(null);
curr.setIso("Suc");
curr.setName("Honorius");
asynchronousRunnerService.runAsynchronously(new AddCurrencyTask(currenciesDao, curr));
}
}
web.xml:
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>Honorius Batch Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
它运行完美,每 5 秒就有一个新数据插入 CurrencyTable。但是,当更新 applicationContext.xml 并创建 CronTriggerSchedler.java 时,CurrencyAddJob.java 中的 applicationContext 和 asynchronousRunnerService 变量将在调试模式下变为 "null"。调用 CurrecnyAddJob.java 后应用程序卡在循环中。
已更新applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<context:component-scan base-package="com.honorius.billing.*">
</context:component-scan>
<context:property-placeholder location="classpath:com"/>
<bean id="honoriusDataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://url address here"/>
<property name="username" value="root"/>
<property name="password" value="password"/>
<property name="jmxEnabled" value="true"/>
<property name="initialSize" value="10"/>
<property name="maxActive" value="2000"/>
<property name="maxIdle" value="500"/>
<property name="minIdle" value="10"/>
<property name="suspectTimeout" value="60"/>
<property name="timeBetweenEvictionRunsMillis" value="30000"/>
<property name="minEvictableIdleTimeMillis" value="60000"/>
<property name="validationQuery" value="select 1 from dual;"/>
<property name="testOnConnect" value="true"/>
<property name="testWhileIdle" value="true"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="honoriusDataSource"/>
</bean>
<bean id="mySched" class="com.honorius.billing.CronTriggerScheduler" init-method="init"></bean>
</beans>
CronTriggerScheduler.java:
public class CronTriggerScheduler {
public void init(){
scheduler();
}
public static void scheduler(){
try {
Scheduler scheduler;
scheduler = new StdSchedulerFactory().getScheduler();
scheduler.start();
JobDetail job = JobBuilder.newJob(CurrencyAddJob.class)
.withIdentity("DailyJobs", "group").build();
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("dailyJobCronTrigger", "group")
.withSchedule(
CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
.build();
scheduler.scheduleJob(job, trigger);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
如何使用 CronTriggerScheduler.java 安排我的应用程序。 任何帮助将不胜感激。
要使依赖注入在您的作业 bean (CurrencyAddJob) 上工作,调度程序必须由 Spring 创建。将 SchedulerFactoryBean 保留在 xml 中,但没有任何作业或触发器。
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="applicationContextSchedulerContextKey" value="applicationContext"/>
</bean>
然后注入CronTriggerScheduler
public class CronTriggerScheduler {
@Autowired
private Scheduler scheduler;
public void init(){
scheduleJob();
}
private void scheduleJob() {
try {
JobDetail job = JobBuilder.newJob(CurrencyAddJob.class)
.withIdentity("DailyJobs", "group").build();
Trigger trigger = TriggerBuilder
.newTrigger()
.withIdentity("dailyJobCronTrigger", "group")
.withSchedule(
CronScheduleBuilder.cronSchedule("0/5 * * * * ?"))
.build();
scheduler.scheduleJob(job, trigger);
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
注意:无需将创建作业的方法设为静态 public。