Bootstrap

Quartz定时器+Spring + @Autowired注入 空指针异常

 

 

在Quartz的定时方法里引用@Autowired注入Bean,会报空指针错误

 

 

解决办法:

第一种方法:(推荐,简单,亲测可行)

使用@Resource(name="指定要注入的Bean"),代替@Autowired即可,指定了要注入的Bean名字,就能找到该Bean,就不会空指针了。

 

@Resource(name = "deviceStateProducerService")
private DeviceStateProducerService deviceStateProducerService;

 

 

示例代码:

看下面红色字体部分

 代码

@Service("microDeviceStateService")
public class MicroDeviceStateServiceImpl implements MicroDeviceStateService {
    
    @Resource(name = "deviceStateProducerService")
    private DeviceStateProducerService deviceStateProducerService;
    
    @Scheduled(cron="0/10 * * * * * ?")
    @Lazy(false)
    public void pingDeviceState() {
        boolean isSuccess = PingUtils.ping("127.0.0.1", 4, 1000);
        MicroDeviceState microDeviceState = new MicroDeviceState();
        if(!isSuccess) {
            logger.debug("连接设备状态失败!");
            microDeviceState.setDeviceState("1");
        }else {
            microDeviceState.setDeviceState("0");
        }
        
        microDeviceState.setDeviceFlag("0");
        microDeviceState.setIp("127.0.0.1");
        DeviceStateBase deviceStateBase = new DeviceStateBase();
        BeanUtils.copyProperties(microDeviceState, deviceStateBase);
        deviceStateProducerService.deviceStateSender(deviceStateBase);
    }
    
    

}

 有的定时器不生效,在类上加注解@EnableScheduling(spring自带的定时任务功能)

 

配置文件

<?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:context="http://www.springframework.org/schema/context"
   xmlns:task="http://www.springframework.org/schema/task"     
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd         
     http://www.springframework.org/schema/context 
      http://www.springframework.org/schema/context/spring-context-3.1.xsd 
     http://www.springframework.org/schema/task 
     http://www.springframework.org/schema/task/spring-task-3.2.xsd" 
     default-lazy-init="true">  


  
    <task:scheduler id="scheduler" pool-size="10" />  
    <task:executor id="executor" keep-alive="3600" pool-size="100-200" 
    queue-capacity="500" rejection-policy="CALLER_RUNS" /> 
    <task:annotation-driven executor="executor" scheduler="scheduler" />
    <!-- 注解配置定时器 -->
    <context:annotation-config /> 
     <!-- spring扫描注解的配置(要扫描的包,即定时器所在包) -->
     <context:component-scan base-package="com.zit.adapter.camera.CameraListener" />
     
</beans>

 

 

 

 

 

第二种方法:(也可行,不推荐)

使用Spring原生获取Bean的方法 取代 @Autowired注入,同时,不要与定时方法在同一个类

 

示例代码:

注解方式写了一个定时方法,方法里需要引用Dao层,插入数据库,

直接@Autowired会报空指针异常,做出如下红色字体改动

public class FTPUtil{

//    @Autowired
//    MicroCameraPassRecordDao microCameraPassRecordDao;

    private static MicroCameraPassRecordDao microCameraPassRecordDao = null;
    
    使用Spring获取注入bean
    static {
        microCameraPassRecordDao = 
                (MicroCameraPassRecordDao) SpringContextUtils.getApplicationContext().getBean("microCameraPassRecordDao");
    }



    /**
    * 定时从FTP下载图片到本地,在这个方法里调用别的Dao层的方法
    */
    @Scheduled(cron="0/20 * * * * * ?")
    @Lazy(false)
    public synchronized void service() {
        FTPUtil ftpUtil = new FTPUtil();
        boolean isConnect = ftpUtil.connectServer();
        //从FTP下载到工程file下
        boolean flag = ftpUtil.download(getFtpPath());
        
        //引用注入Bean,插入数据库
        MicroCameraPassRecord cameraRecord = new MicroCameraPassRecord();
        cameraRecord.setCameraId(deviceID);
        cameraRecord.setAddTime(System.currentTimeMillis());
        microCameraPassRecordDao.insert(cameraRecord);
        
    }
    
}

 getBean(引用类名,开头字母小写)

 

 

 SpringContextUtils

Spring获取Bean的工具类:


package com.zit.util;

import java.util.Map;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Service;


@SuppressWarnings({ "rawtypes", "unchecked" })
@Service("springContextUtils")
public class SpringContextUtils implements ApplicationContextAware {

    private static ApplicationContext applicationContext;
     
    public void setApplicationContext(ApplicationContext arg0)
            throws BeansException {
        applicationContext = arg0;
    }
 
    /**
     * 获取applicationContext对象
     * @return
     */
    public static ApplicationContext getApplicationContext(){
        return applicationContext;
    }
     
    /**
     * 根据bean的id来查找对象
     * @param id
     * @return
     */
    public static Object getBeanById(String id){
        return applicationContext.getBean(id);
    }
     
    /**
     * 根据bean的class来查找对象
     * @param c
     * @return
     */
    public static Object getBeanByClass(Class c){
        return applicationContext.getBean(c);
    }
     
    /**
     * 根据bean的class来查找所有的对象(包括子类)
     * @param c
     * @return
     */
    public static Map getBeansByClass(Class c){
        return applicationContext.getBeansOfType(c);
    }

}

 

;