[英]Spring MVC and Quartz integration
我想用Quartz Scheduler替換Spring MVC Webapp中的TimerTask。 我的spring-quartz.xml:
<bean id="manifestTask" class="it.dhl.wla.quartz.ManifestTask" />
<bean id="manifestJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="manifestTask" />
<property name="targetMethod" value="go" />
</bean>
<bean id="manifestTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="manifestJob" />
<property name="cronExpression" value="59 15 * * * ?" />
</bean>
它與空的go()方法一起工作(僅帶有日志輸出),問題出在我嘗試@Autowire的ManifstTask依賴項上:
public class ManifestTask {
@Autowired
ManifestService manifestService;
private static final Logger LOG = Logger.getLogger(ManifestTask.class);
public void go() {
LOG.info("Manifest quartz task start...");
boolean res=manifestService.doManifest();
LOG.info("Manifest quartz task end: "+res);
}
}
這是啟動時的錯誤:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [it.dhl.wla.service.ManifestService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
ManifestService在其他類中可以自動裝配並且可以工作,在這種石英任務的特定情況下,bean實例化順序似乎是一個問題。
Spring版本是3.0.5,Quartz 1.8.6。
編輯:
在ManifestTask中添加了對ApplicationContext的引用:
@Autowired
ApplicationContext appctx=null;
很好,當石英調用方法go()時,我瀏覽了appctx,但是找不到任何用注解聲明的@Components。 我發現在spring-quartz.xml中聲明的bean。
appctx的具體類是XmlWebApplicationContext。 xml聲明的bean是否在單獨的上下文中? 如何訪問帶注釋的@Components?
您應該使用@Component
注釋ManifestTask
,以便在spring:D時使用。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class ManifestTask {
@Autowired
ManifestService manifestService;
private static final Logger LOG = Logger.getLogger(ManifestTask.class);
public void go() {
LOG.info("Manifest quartz task start...");
boolean res=manifestService.doManifest();
LOG.info("Manifest quartz task end: "+res);
}
}
另外,在查看編輯過的帖子后,我認為您應該閱讀以下答案:
如何將一個項目的spring-config.xml導入另一個項目的spring-config.xml?
我找到了解決方法,但是我不喜歡它。
spring-quartz.xml:
<!-- MANIFEST -->
<bean id="theManifestService" class="it.dhl.wla.service.ManifestService"/>
<bean id="manifestTask" class="it.dhl.wla.quartz.ManifestTask" >
<property name="manifestService" ref="theManifestService"/>
</bean>
<bean id="manifestJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="manifestTask" />
<property name="targetMethod" value="go" />
</bean>
<bean id="manifestTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="manifestJob" />
<property name="cronExpression" value="59 15 * * * ?" />
</bean>
在ManifestTask.java中:
private ManifestService manifestService;
public ManifestService getManifestService() {
return manifestService;
}
public void setManifestService(ManifestService manifestService) {
this.manifestService = manifestService;
}
現在,ManifestService bean和依賴項已在xml中定義。 但是我的ManifestService類仍被注釋為@Component,因為我在某些控制器中使用了它。
我認為現在我有2個獨立的ManifestService實例...
請按照以下步驟將Quartz與Spring Boot集成在一起
1-在pom.xml文件中添加以下依賴項,它也需要spring-context-support
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.3.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
2-創建單獨的xml並在現有的xml中添加以下代碼
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="quartzJob" class="com.mightyjava.quartz.ExecuteUsingQuartz" />
<bean id="jobFactoryBean" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
p:targetObject-ref="quartzJob" p:targetMethod="run" />
<bean id="triggerFactoryBean"
class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"
p:jobDetail-ref="jobFactoryBean" p:cronExpression="0/5 * * * * ?" />
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"
p:triggers-ref="triggerFactoryBean" />
</beans>
3-創建一個包含執行邏輯的類
import java.util.Date;
public class ExecuteUsingQuartz {
public void run() {
System.out.println("Executing using quartz in every 15 seconds " + new Date());
}
}
如果仍然有疑問,請單擊下面的鏈接並觀看現場演示
我懷疑發生的事是在xxxx-servlet.xml Spring內容文件之一中掃描了ManifestService
bean並將其實例化。 在yyyy-servlet.xml中處理/實例化bean時,以這種方式創建的bean不可用。
為了使bean對所有Spring上下文都全局可用,您需要掃描它所屬的包,或者在與Spring上下文加載器偵聽器關聯的applicationContext.xml文件中對其進行定義。 就像是:
web.xml
...
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.