记录持久化的Quartz与Spring整合时遇到的几个坑

   由于工作,quartz需要持久化在数据库中,开启每日凌晨定时任务,在任务处理job中又需要使用到spring管理的service类,故遇到了几个小问题,以此做个记录。

  • 配置spring-quartz文件时,使用的MethodInvokingJobDetailFactoryBean创建jobDetail

     由于quartz使用了持久化,JobStoreTX存储方式,导致NotSerializableException异常。谷歌得知MethodInvokingJobDetailFactoryBean并未实现序列化,使用JobDetailFactoryBean方式创建,并在job类继承QuartzJobBean,创建jobDetail便不会出错。如下:


    
    
        
        
        
    

——————————————————————————————————————————————————————————————————————————————————
//继承QuartzJobBean 类
@DisallowConcurrentExecution
public class TimeQueryContract extends QuartzJobBean {
    /**
     * Execute the actual job. The job data map will already have been
     * applied as bean property values by execute. The contract is
     * exactly the same as for the standard Quartz execute method.
     *
     * @param context
     * @see #execute
     */
    @Override
    protected void executeInternal(JobExecutionContext context) {...}
}

 

  • 注入spring管理的service的服务到job定时操作中,直接@Resource注入

 当时是直接报NullPointerException空指针异常,后又谷歌得知quartz有自己的上下文,spring管理不到,当然无法自动注入,改用在spring-quartz配置文件中直接将此service添加到jobDataMap中,


    
        
        
        


        
            
                
            
        
    

 

这是一个方式可以解决没有持久化的quartz的service注入问题。但由于我的配置是需要持久化的,也就是需要存入数据库,需要序列化jobDetail。但spring的service底层没有实现Serializable接口,故报错NotSerializableException,自己实现Serializable也没用,其后谷歌很久,有重写相关类的方法,和使用sessionfactory,但本人能力还不行,没采用。后终在一位博主那看到将spring的context注入到quartz中

  • 在配置SchedulerFactoryBean时可注入spring上下文


        
        
        
        

        
        
        

        
        
        
        
        
            
                
            
        
    


————————————————————————————————————————————————————————————————————————————————————————
//在job中获取到spring上下文进行service调用
@DisallowConcurrentExecution
public class TimeQueryContract extends QuartzJobBean {
    /**
     * Execute the actual job. The job data map will already have been
     * applied as bean property values by execute. The contract is
     * exactly the same as for the standard Quartz execute method.
     *
     * @param context
     * @see #execute
     */
    @Override
    protected void executeInternal(JobExecutionContext context) {
        System.out.println("开始执行合同日期查询...");
       
        try {
            //获取spring上下文
            ApplicationContext applicationContextKey = (ApplicationContext) context.getScheduler().getContext().get("applicationContextKey");
            //获取service服务
            ContractSignServiceImpl contractSignService = (ContractSignServiceImpl) applicationContextKey.getBean("contractSignServiceImpl");
            System.out.println(contractSignService.queryDate().toString());
        } catch (SchedulerException e) {
            e.printStackTrace();
        }

    }
}

最后解决方法的博主原文

 

走到这步,就解决了我快谷歌一天的难题。目前大概了解如此,算是解决了问题,做个记录,增强印象 

你可能感兴趣的:(个人记录)