Comment utiliser @Autowired dans un travail à Quartz?
j'utilise du quartz avec ressort et je veux injecter/utiliser une autre classe dans la classe d'emploi et je ne sais pas comment le faire correctement
xml:
<beans xmlns="http://www.springframework.org/schema/beans"
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-2.5.xsd">
<!-- Scheduler task -->
<bean name="schedulerTask" class="com.mkyong.quartz.SchedulerTask" />
<!-- Scheduler job -->
<bean name="schedulerJob"
class="org.springframework.scheduling.quartz.JobDetailBean">
<property name="jobClass" value="com.mkyong.quartz.SchedulerJob" />
<property name="jobDataAsMap">
<map>
<entry key="schedulerTask" value-ref="schedulerTask" />
</map>
</property>
</bean>
<!-- Cron Trigger -->
<bean id="cronTrigger"
class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="schedulerJob" />
<property name="cronExpression" value="0/10 * * * * ?" />
</bean>
<!-- Scheduler -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobDetails">
<list>
<ref bean="schedulerJob" />
</list>
</property>
<property name="triggers">
<list>
<ref bean="cronTrigger" />
</list>
</property>
</bean>
</beans>
le quartz de l'emploi:
package com.mkyong.quartz;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class SchedulerJob extends QuartzJobBean
{
private SchedulerTask schedulerTask;
public void setSchedulerTask(SchedulerTask schedulerTask) {
this.schedulerTask = schedulerTask;
}
protected void executeInternal(JobExecutionContext context)
throws JobExecutionException {
schedulerTask.printSchedulerMessage();
}
}
la tâche à accomplir:
package com.mkyong.quartz;
public class SchedulerTask {
public void printSchedulerMessage() {
System.out.println("Struts 2 + Spring + Quartz ......");
}
}
je veux injecter une autre classe DTO qui traite de la base de données dans la classe des tâches pour faire un certain travail de base de données dans la tâche, comment le faire ?
5 réponses
pas sûr si c'est ce que vous voulez, mais vous pouvez passer quelques valeurs de configuration à la tâche Quartz. Je crois que dans votre cas vous pourriez profiter de la propriété jobDataAsMap
que vous avez déjà mis en place, par exemple:
<property name="jobDataAsMap">
<map>
<entry key="schedulerTask" value-ref="schedulerTask" />
<entry key="param1" value="com.custom.package.ClassName"/>
</map>
</property>
alors vous devriez être en mesure d'y accéder dans votre code Java réel de manière manuelle:
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
schedulerTask.printSchedulerMessage();
System.out.println(context.getJobDetail().getJobDataMap().getString("param1"));
}
ou en utilisant l'approche magic Spring - avoir la propriété param1
définie avec getter/setter. Vous pourriez essayer de définir il avec java.lang.Class
taper alors et avoir fait automatiquement (ressort le ferait pour vous):
private Class<?> param1;
// getter & setter
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
schedulerTask.printSchedulerMessage();
System.out.println("Class injected" + getParam1().getName());
}
Je ne l'ai pas testé.
dans votre solution vous utilisez le spring @Autowired annotation dans une classe qui n'est pas instanciée par le Spring. Votre solution fonctionnera toujours si vous supprimez l'annotation @Autowired parce que le Quartz définit la propriété, pas le ressort.
Quartz va essayer de définir chaque clé dans le JobDataMap comme une propriété. Par exemple: puisque vous avez une clé "myDao" Quartz va chercher une méthode appelée "setMyDao" et passer la valeur de la clé dans cette méthode.
si vous voulez que Spring injecte des haricots de printemps dans vos emplois, créer un SpringBeanJobFactory et mettre cela dans votre SchedulerFactoryBean avec la propriété jobFactory dans votre contexte de printemps.
springbeanjobfactory javadoc:
applique le contexte scheduler, la table de données des emplois et les entrées de la table de données des déclencheurs valeur des propriétés des haricots 151910920"
ApplicationContext springContext =
WebApplicationContextUtils.getWebApplicationContext(
ContextLoaderListener.getCurrentWebApplicationContext().getServletContext()
);
Bean bean = (Bean) springContext.getBean("beanName");
bean.method();
comme mentionné dans injecter la référence de grain dans un travail de Quartz au printemps? vous pouvez utiliser le ressort SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
@Named
public class SampleJob implements Job {
@Inject
private AService aService;
@Override
public void execute(JobExecutionContext context)
throws JobExecutionException {
//Do injection with spring
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
aService.doIt();
}
}
comme mentionné il peut ne pas fonctionner sur une certaine version de ressort, mais je l'ai testé sur 4.2.1.Libération qui a bien fonctionné.
c'est ma solution:
public class MySpringBeanJobFactory extends
org.springframework.scheduling.quartz.SpringBeanJobFactory implements
ApplicationContextAware {
private ApplicationContext ctx;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.ctx = applicationContext;
}
@Override
protected Object createJobInstance(TriggerFiredBundle bundle)
throws Exception {
Object jobInstance = super.createJobInstance(bundle);
ctx.getAutowireCapableBeanFactory().autowireBean(jobInstance);
return jobInstance;
}
}
puis config la classe de MySpringBeanJobFactory dans le XML ete
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="jobFactory">
<bean class="com.xxxx.MySpringBeanJobFactory" />
</property>
<property name="configLocation" value="classpath:quartz.properties" />
<property name="triggers">
<list>
<ref bean="cronTrigger"/>
</list>
</property>
</bean>
bonne chance ! :)