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 ?

30
demandé sur STW 2010-11-23 19:28:42

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é.

10
répondu Grzegorz Oledzki 2010-11-23 19:47:34

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"

14
répondu Kieren Dixon 2011-12-01 01:44:05
ApplicationContext springContext = 
    WebApplicationContextUtils.getWebApplicationContext(
        ContextLoaderListener.getCurrentWebApplicationContext().getServletContext()
    );
Bean bean = (Bean) springContext.getBean("beanName");
bean.method();
8
répondu Damian 2012-10-20 23:39:47

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é.

2
répondu Alireza Fattahi 2017-05-23 11:54:20

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 ! :)

0
répondu martin 2016-04-21 02:58:31