在springboot框架上 整合quartz集群,使用数据库模式,报空指针错误

各位牛人,我是基于springboot2.2.7框架整合 quartz,目的是实现一套代码,多节点部署,高可用。
quartz我使用数据库模式,数据库用的是oracle
我现在是设想是,原有springboot程序,使用阿里的数据库连接配置。
定时任务使用c3p0连接池。一个应用使用两套连接。两个数据源。
现根据网上的推荐,进行了整合,报如下错误
空指针错误,quartz定时无法调用userServiceImpl 。


```bash

2021-09-06 10:58:15.413  INFO 8864 --- [           main] cn.task.QuartzApplication                : Starting QuartzApplication on baohy with PID 8864 (D:\project\demo\target\classes started by Think in D:\project\demo)
2021-09-06 10:58:15.417  INFO 8864 --- [           main] cn.task.QuartzApplication                : The following profiles are active: test
2021-09-06 10:58:16.278  INFO 8864 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2021-09-06 10:58:16.314  INFO 8864 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 24ms. Found 0 JPA repository interfaces.
2021-09-06 10:58:16.871  INFO 8864 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8085 (http)
2021-09-06 10:58:16.882  INFO 8864 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2021-09-06 10:58:16.882  INFO 8864 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.34]
2021-09-06 10:58:17.049  INFO 8864 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-09-06 10:58:17.050  INFO 8864 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1558 ms
2021-09-06 10:58:17.722  INFO 8864 --- [           main] org.quartz.impl.StdSchedulerFactory      : Using ConnectionProvider class 'org.quartz.utils.C3p0PoolingConnectionProvider' for data source 'myDS'
2021-09-06 10:58:17.758  INFO 8864 --- [g-Init-Reporter] com.mchange.v2.log.MLog                  : MLog clients using slf4j logging.
com.mchange.v2.cfg.DelayedLogItem [ level -> FINE, text -> "The configuration file for resource identifier '/mchange-log.properties' could not be found. Skipping.", exception -> null]
com.mchange.v2.cfg.DelayedLogItem [ level -> FINE, text -> "The configuration file for resource identifier '/c3p0.properties' could not be found. Skipping.", exception -> null]
2021-09-06 10:58:17.788  INFO 8864 --- [           main] com.mchange.v2.c3p0.C3P0Registry         : Initializing c3p0-0.9.0.2 [built 26-September-2005 12:55:26 -0400; debug? true; trace: 10]
2021-09-06 10:58:17.823  INFO 8864 --- [           main] org.quartz.impl.StdSchedulerFactory      : Using default implementation for ThreadExecutor
2021-09-06 10:58:17.825  INFO 8864 --- [           main] org.quartz.simpl.SimpleThreadPool        : Job execution threads will use class loader of thread: main
2021-09-06 10:58:17.836  INFO 8864 --- [           main] org.quartz.core.SchedulerSignalerImpl    : Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
2021-09-06 10:58:17.836  INFO 8864 --- [           main] org.quartz.core.QuartzScheduler          : Quartz Scheduler v.2.3.2 created.
2021-09-06 10:58:17.837  INFO 8864 --- [           main] o.quartz.impl.jdbcjobstore.JobStoreCMT   : Using db table-based data access locking (synchronization).
2021-09-06 10:58:17.839  INFO 8864 --- [           main] o.quartz.impl.jdbcjobstore.JobStoreCMT   : JobStoreCMT initialized.
2021-09-06 10:58:17.840  INFO 8864 --- [           main] org.quartz.core.QuartzScheduler          : Scheduler meta-data: Quartz Scheduler (v2.3.2) 'EventScheduler' with instanceId 'baohy1630897097824'
  Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
  NOT STARTED.
  Currently in standby mode.
  Number of jobs executed: 0
  Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 50 threads.
  Using job-store 'org.quartz.impl.jdbcjobstore.JobStoreCMT' - which supports persistence. and is clustered.

2021-09-06 10:58:17.840  INFO 8864 --- [           main] org.quartz.impl.StdSchedulerFactory      : Quartz scheduler 'EventScheduler' initialized from an externally provided properties instance.
2021-09-06 10:58:17.840  INFO 8864 --- [           main] org.quartz.impl.StdSchedulerFactory      : Quartz scheduler version: 2.3.2
2021-09-06 10:58:17.841  INFO 8864 --- [           main] org.quartz.core.QuartzScheduler          : JobFactory set to: org.springframework.scheduling.quartz.AdaptableJobFactory@2650f79
2021-09-06 10:58:17.860  INFO 8864 --- [           main] c.mchange.v2.c3p0.PoolBackedDataSource   : Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource@3bd3d05e[ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, description -> null, driverClass -> oracle.jdbc.OracleDriver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 3bd3d05e, idleConnectionTestPeriod -> 50, initialPoolSize -> 3, jdbcUrl -> jdbc:oracle:thin:@127.0.0.1:1521:orcl, loginTimeout -> 0, maxIdleTime -> 0, maxPoolSize -> 10, maxStatements -> 0, maxStatementsPerConnection -> 120, minPoolSize -> 1, numHelperThreads -> 3, preferredTestQuery -> SELECT 'X' from dual, properties -> {user=******, password=******}, propertyCycle -> 300, testConnectionOnCheckin -> true, testConnectionOnCheckout -> false, usesTraditionalReflectiveProxies -> false ]
2021-09-06 10:58:18.207  INFO 8864 --- [           main] o.s.s.quartz.SchedulerFactoryBean        : Starting Quartz Scheduler now
2021-09-06 10:58:18.215  INFO 8864 --- [           main] o.quartz.impl.jdbcjobstore.JobStoreCMT   : ClusterManager: detected 1 failed or restarted instances.
2021-09-06 10:58:18.215  INFO 8864 --- [           main] o.quartz.impl.jdbcjobstore.JobStoreCMT   : ClusterManager: Scanning for instance "baohy1630889337684"'s failed in-progress jobs.
2021-09-06 10:58:18.220  INFO 8864 --- [           main] o.quartz.impl.jdbcjobstore.JobStoreCMT   : ClusterManager: ......Freed 1 acquired trigger(s).
2021-09-06 10:58:18.224  INFO 8864 --- [           main] org.quartz.core.QuartzScheduler          : Scheduler EventScheduler_$_baohy1630897097824 started.
2021-09-06 10:58:18.224  INFO 8864 --- [           main] org.quartz.core.QuartzScheduler          : Scheduler EventScheduler_$_baohy1630897097824 started.
2021-09-06 10:58:18.271 ERROR 8864 --- [eduler_Worker-1] org.quartz.core.JobRunShell              : Job jobOne.mergeOpeJobTask threw an unhandled Exception: 

java.lang.NullPointerException: null
    at cn.task.quartz.JobOne.executeInternal(JobOne.java:17) ~[classes/:na]
    at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:75) ~[spring-context-support-5.2.6.RELEASE.jar:5.2.6.RELEASE]
    at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[quartz-2.3.2.jar:na]
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [quartz-2.3.2.jar:na]

2021-09-06 10:58:18.272 ERROR 8864 --- [eduler_Worker-1] org.quartz.core.ErrorLogger              : Job (jobOne.mergeOpeJobTask threw an exception.

org.quartz.SchedulerException: Job threw an unhandled exception.
    at org.quartz.core.JobRunShell.run(JobRunShell.java:213) ~[quartz-2.3.2.jar:na]
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [quartz-2.3.2.jar:na]
Caused by: java.lang.NullPointerException: null
    at cn.task.quartz.JobOne.executeInternal(JobOne.java:17) ~[classes/:na]
    at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:75) ~[spring-context-support-5.2.6.RELEASE.jar:5.2.6.RELEASE]
    at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[quartz-2.3.2.jar:na]
    ... 1 common frames omitted

2021-09-06 10:58:18.302  INFO 8864 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8085 (http) with context path ''
2021-09-06 10:58:18.305  INFO 8864 --- [           main] cn.task.QuartzApplication                : Started QuartzApplication in 3.328 seconds (JVM running for 4.991)
2021-09-06 10:58:18.309 ERROR 8864 --- [eduler_Worker-2] org.quartz.core.JobRunShell              : Job jobOne.mergeOpeJobTask threw an unhandled Exception: 

java.lang.NullPointerException: null
    at cn.task.quartz.JobOne.executeInternal(JobOne.java:17) ~[classes/:na]
    at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:75) ~[spring-context-support-5.2.6.RELEASE.jar:5.2.6.RELEASE]
    at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[quartz-2.3.2.jar:na]
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [quartz-2.3.2.jar:na]

2021-09-06 10:58:18.309 ERROR 8864 --- [eduler_Worker-2] org.quartz.core.ErrorLogger              : Job (jobOne.mergeOpeJobTask threw an exception.

org.quartz.SchedulerException: Job threw an unhandled exception.
    at org.quartz.core.JobRunShell.run(JobRunShell.java:213) ~[quartz-2.3.2.jar:na]
    at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [quartz-2.3.2.jar:na]
Caused by: java.lang.NullPointerException: null
    at cn.task.quartz.JobOne.executeInternal(JobOne.java:17) ~[classes/:na]
    at org.springframework.scheduling.quartz.QuartzJobBean.execute(QuartzJobBean.java:75) ~[spring-context-support-5.2.6.RELEASE.jar:5.2.6.RELEASE]
    at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[quartz-2.3.2.jar:na]
    ... 1 common frames omitted


    
相关的代码如下:
目录结构:

![img](https://img-mid.csdnimg.cn/release/static/image/mid/ask/978487898036177.png "=600 #left")


这个代码是是用来配置JobConfig信息。



```java
@Configuration
public class JobConfig {

    @Autowired
    private UserService userService;

    @Bean("jobOneDetail")
    public JobDetailFactoryBean jobOneDetailFactoryBean(JobOne jobOne) {
        JobDetailFactoryBean jobDetailFactoryBean =new JobDetailFactoryBean();
        jobDetailFactoryBean.setJobClass(jobOne.getClass());
        //没有绑定触发器仍然保留在Quartz的JobStore中
        jobDetailFactoryBean.setDurability(true);
        jobDetailFactoryBean.setName("jobOneDetailName");
        jobDetailFactoryBean.setGroup("jobOneDetailGroup");

        JobDataMap jobDataMap = new JobDataMap ();
        jobDataMap.put ("userService",userService);
        jobDetailFactoryBean.setJobDataMap(jobDataMap) ;
        return jobDetailFactoryBean;
    }

    @Bean("jobOneTrigger")
    public CronTriggerFactoryBean cronTriggerOneFactoryBean(@Qualifier("jobOneDetail") JobDetailFactoryBean jobDetailFactoryBean){
        CronTriggerFactoryBean cronTriggerFactoryBean=new CronTriggerFactoryBean();
        cronTriggerFactoryBean.setJobDetail(jobDetailFactoryBean.getObject());
        cronTriggerFactoryBean.setCronExpression("*/1 * * * * ?");
        cronTriggerFactoryBean.setName("jobOneTriggerName");
        cronTriggerFactoryBean.setGroup("jobOneTriggerGroup");
        return cronTriggerFactoryBean;
    }


    @Bean("jobTwoDetail")
    public JobDetailFactoryBean jobTwoDetailFactoryBean(JobTwo jobTwo) {
        JobDetailFactoryBean jobDetailFactoryBean =new JobDetailFactoryBean();
        jobDetailFactoryBean.setJobClass(jobTwo.getClass());
        jobDetailFactoryBean.setDurability(true);
        jobDetailFactoryBean.setName("jobTwoDetailName");
        jobDetailFactoryBean.setGroup("jobTwoDetailGroup");
        JobDataMap jobDataMap = new JobDataMap ();
        jobDataMap.put ("userService",userService);
        jobDetailFactoryBean.setJobDataMap(jobDataMap) ;
        return jobDetailFactoryBean;
    }

    @Bean("jobTwoTrigger")
    public CronTriggerFactoryBean cronTriggerTwoFactoryBean(@Qualifier("jobTwoDetail") JobDetailFactoryBean jobDetailFactoryBean){
        CronTriggerFactoryBean cronTriggerFactoryBean=new CronTriggerFactoryBean();
        cronTriggerFactoryBean.setJobDetail(jobDetailFactoryBean.getObject());
        cronTriggerFactoryBean.setCronExpression("*/1 * * * * ?");
        cronTriggerFactoryBean.setName("jobTwoTriggerName");
        cronTriggerFactoryBean.setGroup("jobTwoTriggerGroup");
        return cronTriggerFactoryBean;
    }

}

实现的接口类信息:

@Component
@DisallowConcurrentExecution //保证上一次任务执行完毕再执行下一任务
//@PersistJobDataAfterExecution //上一个任务完成前写入需要被下一个任务获取的变量以及对应的属性值,类似求和累加
public class JobOne  extends QuartzJobBean {
    private UserService userService;

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        userService.getUserInfo();
    }



    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}

通过这个程序访问阿里数据库连接获取连接。
以下程序是出错的点 黑体标注的部分。


```java
@Service
public class UserServiceImpl  implements UserService {


   @Autowired
    private TaskjobMonitorMapper taskjobMonitorMapper;


    @Override
    public void getUserInfo() {
      **  List<TaskjobMonitorBean>    taskjobMonitorBeanList=taskjobMonitorMapper.getTaskJobMonitorList();
        System.out.println("taskMontiSieze===="+taskjobMonitorBeanList.size());**

        System.err.println("调度getUserInfo成功");
    }

    @Override
    public void getUserAddr() {
        System.err.println("调度getUserAddr成功");
    }
}



    
这个是xml文件配置信息如下:
    

    
```java


<!-- 配置Job类 -->
    <!--&lt;!&ndash; 配置JobDetail &ndash;&gt;
    <bean id="springQtzJobMethod" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        &lt;!&ndash; 执行目标job &ndash;&gt;
        <property name="targetObject" ref="jobOne">
        </property>
        &lt;!&ndash; 要执行的方法 &ndash;&gt;
        <property name="targetMethod" value="execute">
        </property>
    </bean>
   -->
    <bean id="cronTriggerFactoryBean" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <property name="jobDetail" ref="mergeOpeJobTask"/>
        <property name="cronExpression" value="*/1 * * * * ? "/>
    </bean>
    <bean id="mergeOpeJobTask" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <property name="group" value="jobOne"/>
        <property name="durability" value="true"/>
        <property name="jobClass" value="cn.task.quartz.JobOne"></property>
    </bean>
<bean id="springJobSchedulerFactoryBean"   lazy-init="true" autowire="no"  class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="autoStartup" value="true" />
    <property name="triggers">
        <list>
            <ref bean="cronTriggerFactoryBean"></ref>
        </list>
    </property>
    <!-- 解决:quartz启用数据库管理模式,启动时报异常【java.io.NotSerializableException:
      Unable to serialize JobDataMap for insertion into database because the value of
      property 'jobLauncher' is not serializable: org.springframework.batch.core.launch.support.SimpleJobLauncher】‍‍ -->
    <property name="schedulerContextAsMap">
        <map>
         <entry key="jobLocator"  value="org.springframework.batch.core.configuration.JobRegistry" />
            <entry key="jobLauncher" value="org.springframework.batch.core.launch.support.SimpleJobLauncher" />
        </map>
    </property>
    <!--可选,QuartzScheduler 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 -->
    <property name="overwriteExistingJobs" value="true"/>
    <!-- 属性 -->
    <property name="quartzProperties">
        <props>
            <!-- 集群要求必须使用持久化存储 -->
            <prop key="org.quartz.jobStore.class">org.quartz.impl.jdbcjobstore.JobStoreCMT</prop>
            <prop key="org.quartz.scheduler.instanceName">EventScheduler</prop>
            <!-- 每个集群节点要有独立的instanceId -->
            <prop key="org.quartz.scheduler.instanceId">AUTO</prop>
            <!-- Configure ThreadPool -->
            <prop key="org.quartz.threadPool.class">org.quartz.simpl.SimpleThreadPool</prop>
            <prop key="org.quartz.threadPool.threadCount">50</prop>
            <prop key="org.quartz.threadPool.threadPriority">5</prop>
            <prop key="org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread">true</prop>
            <!-- Configure JobStore -->
            <prop key="org.quartz.jobStore.misfireThreshold">60000</prop>
            <!--mysql
            <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.StdJDBCDelegate</prop>
            -->
            <!--#持久化方式配置数据驱动,ORACLE数据库-->
            <prop key="org.quartz.jobStore.driverDelegateClass">org.quartz.impl.jdbcjobstore.oracle.OracleDelegate</prop>
            <prop key="org.quartz.jobStore.tablePrefix">qrtz_</prop>
            <prop key="org.quartz.jobStore.maxMisfiresToHandleAtATime">10</prop>
            <!-- 开启集群 -->
            <prop key="org.quartz.jobStore.isClustered">true</prop>
            <prop key="org.quartz.jobStore.clusterCheckinInterval">5000</prop>
            <prop key="org.quartz.jobStore.dontSetAutoCommitFalse">true</prop>
            <prop key="org.quartz.jobStore.txIsolationLevelSerializable">false</prop>
            <prop key="org.quartz.jobStore.dataSource">myDS</prop>
            <prop key="org.quartz.jobStore.nonManagedTXDataSource">myDS</prop>
            <prop key="org.quartz.jobStore.useProperties">false</prop>
            <!-- Configure Datasources -->
            <prop key="org.quartz.dataSource.myDS.driver">oracle.jdbc.OracleDriver</prop>
            <prop key="org.quartz.dataSource.myDS.URL">jdbc:oracle:thin:@127.0.0.1:1521:orcl</prop>
            <prop key="org.quartz.dataSource.myDS.user">system</prop>
            <prop key="org.quartz.dataSource.myDS.password">123456</prop>
            <prop key="org.quartz.dataSource.myDS.maxConnections">10</prop>
            <prop key="org.quartz.dataSource.myDS.validationQuery">SELECT 'X' from dual </prop>
        </props>
    </property>
    <property name="applicationContextSchedulerContextKey" value="applicationContext" />
</bean>
</beans>    

望采纳,这里 new 一下


 List<TaskjobMonitorBean>    taskjobMonitorBeanList  = new  List<TaskjobMonitorBean>   ();

springboot就别搞这些花里胡哨的配置了,只注入job就行了