最近在做企业开发的时候,有个需求需要我对发送邮件的定时调度任务做调整和优化。

@Scheduled 定时调度任务

已经完成的发送邮件定时调度任务大概长这样:

首先,思考内部类是怎么运行的。我们知道在内部类编译成功后,它会产生一个新的class文件。

该class文件仅仅只保留了对外部类的引用。

举个例子,当外部类传入的参数需要被内部类调用时,直接看起来好像就是被直接调用的:

1
2
3
4
5
6
7
8
9
10
@Component
public class EmailScheduled{

@Scheduled(cron = "0 0 23 * * * ?")
public void emailSend(){
...

}
}

优化调整的困难点在于debug麻烦:

  • 目前的开发环境的代码并没有设置统一接口来通过前端调试后端定时任务
  • 如果通过修改cron来调试,需要重启项目,更重要的是会发很多骚扰邮件出去
  • 还有一个思路是在测试代码里面调用方法,但是也很麻烦

实际上还有一个比较简洁的思路,重写*InitialzingBean类的afterPropertiesSet*方法。

spring初始化bean的时候,如果bean实现了*InitializingBean接口,会自动调用afterPropertiesSet*方法,所以可以想到,通过这样的方式,就可以通过重启打断点进行调试了:

1
2
3
4
5
6
7
8
9
10
11
12
13
@Component
public class EmailScheduled{

@Scheduled(cron = "0 0 23 * * * ?")
public void emailSend(){
...
}

@Override
public void afterPropertiesSet() throws Exception{
emailSend();
}
}

是不是很简单?当然,这可能不是最优解,但是如果只在项目中短暂使用,也是问题不大的。