quartz集群化MethodInvokingJobDetailFactoryBean无法序列化

1.问题描述

由于spring的bug(具体原因可在github上搜索),使用MethodInvokingJobDetailFactoryBean配置jobdetail后,启动quartz集群时此类无法序列化

2.解决方案

根据git上提供的解决办法,重新MethodInvokingJobDetailFactoryBean为BeanInvokingJobDetailFactoryBean,但git上提供的代码在高版本中不适用。下面贴出修改后的代码

@Component
public class BeanInvokingJobDetailFactoryBean implements
        FactoryBean, BeanNameAware, InitializingBean, ApplicationContextAware
{
    protected static ApplicationContext applicationContext;
    private Log logger = LogFactory.getLog(getClass());
    private String group = Scheduler.DEFAULT_GROUP;
    private boolean concurrent = true;
    private boolean durable = false;
    private boolean volatility = false;
    private boolean shouldRecover = false;
    private String[] jobListenerNames;
    private String beanName;
    private JobDetail jobDetail;
    private String targetBean;
    private String targetMethod;
    private Object[] arguments;

    //  targetBean getter setter 省略
    //  targetMethod getter setter 省略
    @Override
    public JobDetail getObject() throws Exception
    {
        return jobDetail;
    }
    @Override
    public Class getObjectType()
    {
        return JobDetail.class;
    }
    @Override
    public boolean isSingleton()
    {
        return true;
    }
    @Override
    public void setBeanName(String beanName)
    {
        this.beanName = beanName;
    }
    @Override
    public void afterPropertiesSet() throws Exception
    {
        try
        {
            logger.debug("start");
            logger.debug("Creating JobDetail "+beanName);
            JobDetailImpl jdi = new JobDetailImpl();
            jdi.setName(beanName);
            jdi.setGroup(group);
            jdi.setJobClass(concurrent ? BeanInvokingJob.class :
                    StatefulBeanInvokingJob.class);
            jdi.setDurability(durable);
//            jdi.setVolatility(volatility);
            jdi.setRequestsRecovery(shouldRecover);
            this.jobDetail = jdi;
            jobDetail.getJobDataMap().put("targetBean", targetBean);
            jobDetail.getJobDataMap().put("targetMethod", targetMethod);
            jobDetail.getJobDataMap().put("arguments", arguments);

            logger.debug("Registering JobListener names with JobDetail object "+beanName);
//            if (this.jobListenerNames != null) {
//                for (int i = 0; i < this.jobListenerNames.length; i++) {
//                    this.jobDetail.addJobListener(this.jobListenerNames[i]);
//                }
//            }
            logger.info("Created JobDetail: "+jobDetail+"; targetBean: "+
                    targetBean+"; targetMethod: "+targetMethod+"; arguments: "+arguments+";");
        }
        finally
        {
            logger.debug("end");
        }
    }
    public void setConcurrent(boolean concurrent)
    {
        this.concurrent = concurrent;
    }
    public void setDurable(boolean durable)
    {
        this.durable = durable;
    }
    public void setGroup(String group)
    {
        this.group = group;
    }
    public void setJobListenerNames(String[] jobListenerNames)
    {
        this.jobListenerNames = jobListenerNames;
    }
    public void setShouldRecover(boolean shouldRecover)
    {
        this.shouldRecover = shouldRecover;
    }
    public void setVolatility(boolean volatility)
    {
        this.volatility = volatility;
    }
    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException
    {
        applicationContext = context;
    }

    public void setArguments(Object[] arguments)
    {
        this.arguments = arguments;
    }

    public void setJobDetail(JobDetail jobDetail) {
        this.jobDetail = jobDetail;
    }

    public void setTargetBean(String targetBean) {
        this.targetBean = targetBean;
    }

    public void setTargetMethod(String targetMethod) {
        this.targetMethod = targetMethod;
    }

    public static class BeanInvokingJob implements Job
    {
        protected Log logger = LogFactory.getLog(getClass());
        @Override
        public void execute(JobExecutionContext context) throws JobExecutionException
        {
            try
            {
                logger.debug("start");

                String targetBean = context.getMergedJobDataMap().getString("targetBean");
                logger.debug("targetBean is "+targetBean);
                if(targetBean==null){
                    throw new JobExecutionException("targetBean cannot be null.", false);
                }
                String targetMethod = context.getMergedJobDataMap().getString("targetMethod");
                logger.debug("targetMethod is "+targetMethod);
                if(targetMethod==null){
                    throw new JobExecutionException("targetMethod cannot be null.", false);
                }
                Object argumentsObject = context.getMergedJobDataMap().get("arguments");
                Object[] arguments = (argumentsObject instanceof String) ? null :
                        (Object[])argumentsObject;
                logger.debug("arguments array is "+arguments);

                Object bean = applicationContext.getBean(targetBean);
                logger.debug("applicationContext resolved bean name/id '"+targetBean+"' to "+bean);

                MethodInvoker beanMethod = new MethodInvoker();
                beanMethod.setTargetObject(bean);
                beanMethod.setTargetMethod(targetMethod);
                beanMethod.setArguments(arguments);
                beanMethod.prepare();
                logger.info("Invoking Bean: "+targetBean+"; Method: "+
                        targetMethod+"; arguments: "+arguments+";");
                beanMethod.invoke();
            }
            catch(JobExecutionException e)
            {
                throw e;
            }
            catch(Exception e)
            {
                throw new JobExecutionException(e);
            }
            finally
            {
                logger.debug("end");
            }
        }
    }
    public static class StatefulBeanInvokingJob extends BeanInvokingJob implements StatefulJob
    {
        // No additional functionality; just needs to implement StatefulJob.
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容