来公司的第二周接到了定时任务的开发需求: 每天早上十点发送用户报表邮件 . 校招新人菜鸟没做过这玩意有些懵 (尴尬) 于是决定分步写, 从 Excel 导出 ->邮件发送 ->定时器实现 ->mapper 层返回集接收, 前几步都没啥问题, 都在 service 层, 可以用 main 方法单独测试下, 可以发送邮件, 但是通过 service 调用 mapper 时问题就来了 -- 菜鸟踩坑了, 抛出 java.lang.NullPointerException, 下图是代码:
- @Component
- @EnableScheduling
- @Service("cronTaskService")
- public class CronTaskServiceImpl implements CronTaskService {
- @Resource
- private ExportExcelServiceImpl exportExcelService;
- @Resource
- private MailSendServiceImpl mailSendService;
- private final static Logger log = LoggerFactory.getLogger(CronTaskServiceImpl.class);
- private static int Count = 0;
- @Scheduled(cron = "*/10 * * * * ?")
- @Override
- public void out(){
- new ExportExcelServiceImpl().exportExcel("zhoubaobiao1");
- //String filePath = exportExcelService.exportExcel("周报表" + Count++ + ".xls");
- //mailSendService.sendEmail(filePath);
- log.info("-----------success-------\n");
- }
- }
问了组内的前辈(应该也是没做几年), 问题解决不了, 定位不对. 后面又在网上找了许久, 在一位博主博文中找到了原因, 链接: https://blog.csdn.net/itguangit/article/details/78305278
我的想法是通过 new()方法创建 ExportExcelServiceImpl 对象调用 exportExcel()方法, exportExcel()方法中调用 mapper 层连接云上库, 然后实现导出 Excel 数据表到本地, 结果就出现了空指针异常
- [] 2019-12-19 13:22:20.003 [pool-1-thread-1] ERROR o.s.s.support.TaskUtils$LoggingErrorHandler - Unexpected error occurred in scheduled task.
- java.lang.NullPointerException: null
- at com.titansaas.cronjob.service.impl.ExportExcelServiceImpl.exportExcel(ExportExcelServiceImpl.java:116)
- at com.titansaas.cronjob.service.impl.CronTaskServiceImpl.out(CronTaskServiceImpl.java:36)
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
- at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
- at java.lang.reflect.Method.invoke(Method.java:498)
- at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
- at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
- at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
- at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
- at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
- at java.util.concurrent.FutureTask.run(FutureTask.java)
- at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
- at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
- at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
- at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
- at java.lang.Thread.run(Thread.java:748)
想法比较美好, 但是初接触 springboot 不知道一个关键问题, new()出来的对象, 无论是在对象或是在对象内部通过注解 @Resource 或者是 @Autowired 实现自动装配, 或者是对方法进行 @PostConstruct 标记 (又挖坑坑自己, 引发其他一系列问题), 期望 spring 扫描到其中的 mapper 对象, 都做不到; spring 不会对其进行自动装配 bean, 注入 mapper 失败, 导致 mapper 层映射无法完成, 写好的 xml 中的 SQL 无法执行. 后来在上博文中找到了原因, 重新通过 @Resource 注解注册上面几个 Service 层对象, 让 spring 自己完成创建和装配, 才解决了问题. 不复杂, 但是网上很多地方的答案不是需要的, 问题定位由于缺乏经验还是花了些时间(哈哈??) 如有不对请指教, 程序猿学习 ing...
来源: http://www.bubuko.com/infodetail-3339501.html