首页 > 代码库 > Spring quartz定时任务service注入问题

Spring quartz定时任务service注入问题

今天想单元测试一下spring中的quartz定时任务,一顿折腾,到最后总是发现job类里注入的service为null。一开始还以为spring的配置问题,各种找原因,最后还是确定是没有注入。

就去网上搜搜吧。也找出来一些眉目。简单的理解这个原因是job是在quartz中实例化出来的,不受spring的管理。所以就导致注入不进去了。参考这个文章

http://www.tuicool.com/articles/Qjyamu

找着试试的态度,就按照文章里说的。new一个类

public class MyJobFactory extends AdaptableJobFactory {

    //这个对象Spring会帮我们自动注入进来,也属于Spring技术范畴.
    @Autowired
    private AutowireCapableBeanFactory capableBeanFactory;
    
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        //调用父类的方法
        Object jobInstance = super.createJobInstance(bundle);
        //进行注入,这属于Spring的技术,不清楚的可以查看Spring的API.
        capableBeanFactory.autowireBean(jobInstance);
        return jobInstance;
    }
}

接下来把他配置到Spring当中去

<bean id="jobFactory" class="com.gary.operation.jobdemo.demo1.MyJobFactory"></bean>

然后在把org.springframework.scheduling.quartz.SchedulerFactoryBean的jobFactory设置成我们自己的。

<bean name="MyScheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
  <!-- 其他属性省略 -->
  <property name="jobFactory" ref="jobFactory"></property>
</bean>

这样就ok了。

 

问题算是解决了吧,但是想着还要自己实现这些东西,对框架有侵入。就试着找找其它方法。

 

正好前几天写spring和quartz的例子的时候,一个文章介绍了spring下quartz定时任务的两种方式。博文地址http://kevin19900306.iteye.com/blog/1397744

一个是继承QuartzJobBean,另一个不用继承,单纯的java类。我想QuartzJobBean是spring里的类,这样的话这个方式的定时任务类是否就是spring来管理的。注入应该就没问题了吧。

这是一个很小的项目,实验起来也很简单,就启动,debug。发现还是注入不进去。就接着试第二种方式,debug。惊奇的发现注入没问题了。

到此为止,这个问题已经解决了。当然还是最后一种方式合理简单。

 

貌似不能上传附件就把所有源码贴过来吧。

目录结构为

技术分享

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <packaging>war</packaging>

  <name>test</name>
  <groupId>test</groupId>
  <artifactId>test</artifactId>
  <version>1.0-SNAPSHOT</version>
  <properties>
    <springframework.version>3.0.5.RELEASE</springframework.version>
  </properties>
  <dependencies>


    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${springframework.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${springframework.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${springframework.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${springframework.version}</version>
    </dependency>

    <dependency>
      <groupId>org.quartz-scheduler</groupId>
      <artifactId>quartz</artifactId>
      <version>1.8.5</version>
    </dependency>
  </dependencies>

</project>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
         xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
</web-app>
        

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
  <context:component-scan base-package="com.dupang.*" />

  <bean id="jobFactory" class="com.dupang.util.MyJobFactory"></bean>

  <!-- 配置调度程序quartz ,其中配置JobDetail有两种方式-->
  <!--方式一:使用JobDetailBean,任务类必须实现Job接口 -->
  <bean id="myjob" class="org.springframework.scheduling.quartz.JobDetailBean">
    <property name="name" value="exampleJob"></property>
    <property name="jobClass" value="com.dupang.quartz.SpringQtz1"></property>
    <property name="jobDataAsMap">
    <map>
      <entry key="service"><value>simple is the beat</value></entry>
    </map>
    </property>
  </bean>
  <!--运行时请将方式一注释掉! -->
  <!-- 方式二:使用MethodInvokingJobDetailFactoryBean,任务类可以不实现Job接口,通过targetMethod指定调用方法-->
  <!-- 定义目标bean和bean中的方法 -->
  <bean id="SpringQtzJob" class="com.dupang.quartz.SpringQtz2"/>
  <bean id="SpringQtzJobMethod" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <property name="targetObject">
      <ref bean="SpringQtzJob"/>
    </property>
    <property name="targetMethod">  <!-- 要执行的方法名称 -->
      <value>execute</value>
    </property>
  </bean>

  <!-- ======================== 调度触发器 ======================== -->
  <bean id="CronTriggerBean" class="org.springframework.scheduling.quartz.CronTriggerBean">
    <property name="jobDetail" ref="SpringQtzJobMethod"></property>
    <property name="cronExpression" value="0/5 * * * * ?"></property>
  </bean>

  <!-- ======================== 调度工厂 ======================== -->
  <bean id="SpringJobSchedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="triggers">
      <list>
        <ref bean="CronTriggerBean"/>
      </list>
    </property>
  </bean>

</beans>
MyJobFactory
package com.dupang.util;

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;

/**
 * Created by dupang on 2016/11/14.
 */
public class MyJobFactory extends AdaptableJobFactory {

    //这个对象Spring会帮我们自动注入进来,也属于Spring技术范畴.
    @Autowired
    private AutowireCapableBeanFactory capableBeanFactory;

    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        //调用父类的方法
        Object jobInstance = super.createJobInstance(bundle);
        //进行注入,这属于Spring的技术,不清楚的可以查看Spring的API.
        capableBeanFactory.autowireBean(jobInstance);
        return jobInstance;
    }
}
HelloService
package com.dupang.service;

/**
 * Created by dupang on 2016/11/14.
 */
public interface HelloService {

    void sayHello(String name);
}
HelloServiceImpl

package com.dupang.impl;

import com.dupang.service.HelloService;
import com.sun.javafx.collections.SourceAdapterChange;
import org.springframework.stereotype.Service;

/**
 * Created by dupang on 2016/11/14.
 */
@Service
public class HelloServiceImpl implements HelloService {
    public void sayHello(String name) {
        System.out.println("Hello to"+ name);
    }
}

SpringQtz1
package com.dupang.quartz;

import com.dupang.service.HelloService;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

import javax.annotation.Resource;
import java.util.Date;

/**
 * Created by Administrator on 2016/11/9.
 */
public class SpringQtz1 extends QuartzJobBean {

    @Resource
    HelloService helloService;
    private static int counter = 0;
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        helloService.sayHello("dupang");
    }
}
SpringQtz2
package com.dupang.quartz;

import com.dupang.service.HelloService;

import javax.annotation.Resource;
import java.util.Date;

/**
 * Created by Administrator on 2016/11/9.
 */
public class SpringQtz2 {
    private static int counter = 0;
    @Resource
    HelloService helloService;
    protected void execute() {
        helloService.sayHello("dupang");
    }
}


需要源码的留言

 
 
 

Spring quartz定时任务service注入问题