Как использовать @Autowired в Quartz Job? - PullRequest
32 голосов
/ 23 ноября 2010

я использую кварц с пружиной и я хочу внедрить / использовать другой класс в классе работы и я не знаю, как это сделать правильно

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>

кварцевое задание:

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();

    }
}

задача для выполнения:

package com.mkyong.quartz;

public class SchedulerTask {

   public void printSchedulerMessage() {

       System.out.println("Struts 2 + Spring + Quartz ......");

   }
}

я хочу добавить другой класс DTO, который имеет дело с базой данных в классе задачи как сделать работу с базой данных в задаче, как это сделать?

Ответы [ 5 ]

14 голосов
/ 01 декабря 2011

В вашем решении вы используете аннотацию Spring @Autowired в классе, который не был создан в Spring. Ваше решение будет по-прежнему работать, если вы удалите аннотацию @Autowired, потому что Quartz задает свойство, а не Spring.

Кварц будет пытаться установить каждый ключ в JobDataMap как свойство. Например. так как у вас есть ключ «myDao», Quartz будет искать метод с именем «setMyDao» и передавать значение ключа в этот метод.

Если вы хотите, чтобы Spring вставлял Spring Bean в ваши задания, создайте SpringBeanJobFactory и установите его в свой SchedulerFactoryBean с помощью свойства jobFactory в контексте Spring.

SpringBeanJobFactory javadoc:

Применяет контекст планировщика, карту данных задания и триггерные записи карты данных. в качестве значения свойства bean

10 голосов
/ 23 ноября 2010

Не уверен, что это именно то, что вам нужно, но вы можете передать некоторые значения конфигурации в задание Quartz. Я полагаю, что в вашем случае вы могли бы воспользоваться уже установленным свойством jobDataAsMap, например:

 <property name="jobDataAsMap">
    <map>
      <entry key="schedulerTask" value-ref="schedulerTask" />
      <entry key="param1" value="com.custom.package.ClassName"/>
     </map>
  </property>

Тогда вы сможете получить к нему доступ в своем фактическом коде Java вручную:

protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
    schedulerTask.printSchedulerMessage();
    System.out.println(context.getJobDetail().getJobDataMap().getString("param1"));
}

Или используя волшебный подход Spring - определите свойство param1 с помощью getter / setter. Вы можете попытаться определить его с помощью типа java.lang.Class и сделать это автоматически (Spring сделает это за вас):

 private Class<?> param1;

 // getter & setter

 protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
    schedulerTask.printSchedulerMessage();
    System.out.println("Class injected" + getParam1().getName());
 }     

Хотя я не проверял это.

9 голосов
/ 21 октября 2012
ApplicationContext springContext = 
    WebApplicationContextUtils.getWebApplicationContext(
        ContextLoaderListener.getCurrentWebApplicationContext().getServletContext()
    );
Bean bean = (Bean) springContext.getBean("beanName");
bean.method();
3 голосов
/ 12 октября 2015

Как уже упоминалось в добавить ссылку на компонент в задание Quartz весной? вы можете использовать пружину 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();
       }
}

Как уже упоминалось, он может не работать на какой-то весенней версии, но я проверил его на 4.2.1. РЕЛИЗ, который работал нормально.

0 голосов
/ 21 апреля 2016

это мое решение:

    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;
    }
}

затем настройте класс MySpringBeanJobFactory в xml:

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

Удачи! :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...