如何在Quartz Job中使用@Autowired?

Mah*_*leh 33 spring spring-mvc quartz-scheduler

我正在使用石英和弹簧,我想在工作类中注入/使用另一个类,我不知道如何正确地做到这一点

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>
Run Code Online (Sandbox Code Playgroud)

石英工作:

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

    }
}
Run Code Online (Sandbox Code Playgroud)

要执行的任务:

package com.mkyong.quartz;

public class SchedulerTask {

   public void printSchedulerMessage() {

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

   }
}
Run Code Online (Sandbox Code Playgroud)

我想在任务类中注入另一个处理数据库的DTO类来完成任务中的数据库工作,怎么做?

Kie*_*xon 14

在您的解决方案中,您在未由Spring实例化的类中使用spring @Autowired批注.如果删除@Autowired注释,您的解决方案仍然有效,因为Quartz正在设置属性,而不是Spring.

Quartz将尝试将JobDataMap中的每个键设置为属性.例如,因为你有一个键"myDao",Quartz将寻找一个名为"setMyDao"的方法,并将键值传递给该方法.

如果您希望Spring将spring bean注入您的作业,请创建一个SpringBeanJobFactory并使用spring上下文中的jobFactory属性将其设置为SchedulerFactoryBean .

SpringBeanJobFactory javadoc:

将调度程序上下文,作业数据映射和触发器数据映射条目应用为bean属性值

  • 对于那些有兴趣的人,你可以在这个答案中找到一个`SpringBeanJobFactory`实现自动自动装配Quartz作业(包括完整的例子):http://stackoverflow.com/a/15211030/787375 (7认同)

Grz*_*zki 10

不确定这是否是您想要的,但您可以将一些配置值传递给Quartz作业.我相信你的情况下你可以利用jobDataAsMap你已经建立的财产,例如:

 <property name="jobDataAsMap">
    <map>
      <entry key="schedulerTask" value-ref="schedulerTask" />
      <entry key="param1" value="com.custom.package.ClassName"/>
     </map>
  </property>
Run Code Online (Sandbox Code Playgroud)

然后,您应该能够以手动方式在实际Java代码中访问它:

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

或者使用神奇的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());
 }     
Run Code Online (Sandbox Code Playgroud)

我没有测试过它.

  • 在您写的问题中,您想要使用该类,而不是对象.无论如何,那有什么区别呢? (2认同)

小智 9

ApplicationContext springContext = 
    WebApplicationContextUtils.getWebApplicationContext(
        ContextLoaderListener.getCurrentWebApplicationContext().getServletContext()
    );
Bean bean = (Bean) springContext.getBean("beanName");
bean.method();
Run Code Online (Sandbox Code Playgroud)

  • 为什么您认为OP在Web环境中运行? (3认同)