关于quartz框架底层的问题

关于quartz框架底层的问题

老师您好,

跟着老师的quartz案例写了个一模一样的配置类,但spring boot无法正常启动。已经在另一个问题中提问,这里不讨论那个问题。自己百度了一些博客,学着自己写一个quartz,经过多次测试,已经可以正常定时访问数据库写入昨天商品销量记录。但过程中有一些问题不懂,源码也看不懂,这里想问一下老师:

下面是将QuartzConfig的main方法一起放到spring boot入口类的main方法当中,

问:直接在入口类加上其他配置类的main方法,对项目启动,或内存,会有不良影响吗?

@SpringBootApplication
@ImportResource("classpath:spring/spring_transaction.xml")
public class O2oApplication {

   public static void main(String[] args) {
       SpringApplication.run(O2oApplication.class, args);
       QuartzConfig.main(args);
   }
}

下面是QuartzConfig入口类,麻烦老师帮我看一下这样写对 ”校园商铺“ 项目是否OK?

如果是大型的项目,这样写还OK吗?实现工作中通常是什么样的思路写QuartzConfig类?

public class QuartzConfig {

   public static void main(String[] args) {

       args = null;

       //测试用
       String cron = "0/3 * * * * ? *";

//        String cron = "0 0 0 * * ? *";
       JobDetail jobDetail = JobBuilder.newJob(ProductSellDailyJob.class)
               .withIdentity("product_sell_daily_job","product_sell_daily_job_group")
               .build();
       CronTrigger cronTrigger = TriggerBuilder.newTrigger()
               .withIdentity("product_sell_daily_job", "product_sell_daily_job_group")
               .withSchedule(cronSchedule(cron))
               .build();
       try {
           Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();;
           scheduler.scheduleJob(jobDetail, cronTrigger);
           scheduler.start();
       } catch (SchedulerException e) {
           e.printStackTrace();
       }
   }
}

下面是Job接口的实现类ProductSellDailyJob,

问:

为什么一定要静态属性才能被execute(JobExecutionContext jobExecutionContext)方法访问?

普通属性即使在setApplicationContext(ApplicationContext applicationContext)方法中赋值完成后,在execute(JobExecutionContext jobExecutionContext)方法中访问,结果对象为null。


/**
* 在quartz框架中,jobDetail的构造类JobBuilder的静态newJob(class)方法:
* JobBuilder.newJob(ProductSellDailyJob.class),ProductSellDailyJob就是Job接口的实现类。
* 在构造jobDetail对象的过程原理有待探索,但实际测试发现:
* 就是Job接口的实现类当中的所有属性必须要是静态才能被Job接口的
* execute(JobExecutionContext jobExecutionContext)方法访问到,
* 如果Job接口的实现类的属性没有使用static,
* 那么execute(JobExecutionContext jobExecutionContext)将无法访问到该属性。
*/
@Configuration
public class ProductSellDailyJob implements Job, ApplicationContextAware {

   //这里的applicationContext因为没有使用static,所以在下面execute()方法中是无法访问的。
   //即使在execute()方法中使用applicationContext得到的对象也是null
   private ApplicationContext applicationContext;

   //只有使用static的静态属性才能被execute()方法正常访问和使用。
   private static ProductSellDailyService productSellDailyService;

   @Override
   public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
       //这里给applicationContext赋值,在其他方法可以访问到,
       //但如果在execute()方法内访问的话,是访问不到的,对象为Null
       this.applicationContext = applicationContext;
       //只有使用static的静态属性才能被execute()方法正常访问和使用。
       productSellDailyService = (ProductSellDailyService)applicationContext.getBean("productSellDailyService");
   }

   @Override
   public void execute(JobExecutionContext jobExecutionContext) {
       try {
           productSellDailyService.addProductSellDaily();
       } catch (Exception e) {
           System.out.println("productSellDailyService.addProductSellDaily():"+e.getMessage());
       }
       System.out.println("job执行时间:"+new Date().toString());
   }
}

正在回答 回答被采纳积分+1

登陆购买课程后可参与讨论,去登陆

2回答
好帮手慕小脸 2020-05-21 19:27:33

同学你好,

1、应该是不会有影响的

2、类加载时执行,然后在execute里面调用那个私有化属性,就必须加上static,要不然是加载不到的。

注:如果加上static,在类加载时就会加载

祝学习愉快~


好帮手慕小脸 2020-05-21 17:40:58

同学你好,

1、直接在入口类加上其他配置类的main方法,对项目启动,或内存,会有不良影响吗?

@ImportResource:是导入Spring的配置文件,让配置文件里面的内容生效;

@ImportResource:通过locations属性加载对应的xml配置文件,可能需要配合其它注解一起使用。

2、大型的项目,要注意定时器效率怎么样。要根据实际业务需求配置定时器,写QuartzConfig类。

3、ProductSellDailyJob类的execute方法中 用到了属性productSellDailyService。

同学可以启动项目看一下执行execute方法的时候productSellDailyService是否为null。
或者可以在属性上加@Autowired启动试试,看productSellDailyService是否为null。

祝学习愉快~


  • 提问者 超人迪加123 #1
    老师您好, 看样子我应该是表达的不清楚。把QuartzConfig类的main方法在spring boot的入口类里面的main方法中引用,这样子: public static void main(String[] args) { SpringApplication.run(O2oApplication.class, args); QuartzConfig.main(args); } 会对spring boot启动有不良影响吗? 第3点:ProductSellDailyJob类的execute方法中 用到了属性productSellDailyService。 同学可以启动项目看一下执行execute方法的时候productSellDailyService是否为null。 或者可以在属性上加@Autowired启动试试,看productSellDailyService是否为null。 这部分操作我已经测试了好多次了,使用@Autowired或@Resource等依赖注入在除execute方法外的其他方法都能正常获取到要注入的对象。但@Autowired注解注入的属性放在execute方法中使用时,对象会直接变成Null,包括applicationContext对象也是也会变成null。必须要把属性设置为static静态才能在execute方法中使用。因为源码看不懂,所以想问一下老师,给老师添麻烦了
    2020-05-21 17:56:48
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星

相似问题

登录后可查看更多问答,登录/注册

请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师