我是靠谱客的博主 孝顺糖豆,最近开发中收集的这篇文章主要介绍spring的TimerTask注入service为空的解决办法之一,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

因项目需求需要执行定时任务,写完后一直报空指针异常,解决方式如下:

思路来自:https://blog.csdn.net/m912595719/article/details/68945990

1、创建任务类,继承TimerTask类

package com.mes.web.controller.llm.Task;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimerTask;
import com.mes.entity.check.PatrolCheck;
import com.mes.entity.check.ReportCheck;
import com.mes.entity.check.TreeCheck;
import com.mes.entity.llm.FillRecord;
import com.mes.entity.warning.Warning;
import com.mes.service.llm.ChartLlmService;
import com.mes.service.warning.WarningService;
import com.mes.utils.PushExample;
/**
* 执行任务
* @Title:RunTask
* @Package com.mes.web.controller.llm.Task
* @author llm
* @date 2019年6月6日
* @version 1.0
*/
public class RankTask extends TimerTask{
private ChartLlmService chartLlmService;
private WarningService warningService;
public RankTask(ChartLlmService chartLlmService, WarningService warningService){
this.chartLlmService = chartLlmService;
this.warningService = warningService;
}
public RankTask(){
super();
}
/**
*
质检填报查询
*/
@Override
public void run() {
//查询质检部门员工的权限
List<FillRecord> list = chartLlmService.selectMenuByDepartment();
System.out.pringln(list);
}
}

2、实现JAVA EE的监听接口,定时调用任务类

package com.mes.web.controller.llm.Task;
import java.util.Timer;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.mes.service.llm.ChartLlmService;
import com.mes.service.warning.WarningService;
/**
*
* @Title:RankTaskListener
* @Package com.mes.web.controller.llm.Task
* @author llm
* @date 2019年6月6日
* @version 1.0
*/
public class RankTaskListener implements ServletContextListener{
Timer timer = null;
/**
* 监听任务
* @param sce
*/
@Override
public void contextInitialized(ServletContextEvent sce) {
//通过工具类获取spring容器的引用
ChartLlmService chartLlmService = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext()).getBean(ChartLlmService.class);
WarningService warningService = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext()).getBean(WarningService.class);
timer = new Timer(true);
//参数内容(1、定时任务类的带参构造函数,2、项目启动后延迟多久执行任务,3、任务间隔多久再次执行)
timer.schedule(new RankTask(chartLlmService, warningService), 0, 24 * 60 * 60 * 1000);
}
/**
* @param sce
*/
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}

3、在web.xml中先配置初始化spring容器的Listener,然后在配置自己的Listener(注,必须先配置sping的Listener

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:application-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.mes.web.controller.llm.Task.RankTaskListener</listener-class>
</listener>

解释说明:

1、首先要区分Listener的生命周期和spring管理的bean的生命周期。

(1)Listener的生命周期是由servlet容器(例如tomcat)管理的,项目启动时上例中的RankTaskListener是由servlet容器实例化并调用其contextInitialized方法,而servlet容器并不认得@Source注解,因此导致service实例注入失败。

(2)而spring容器中的bean的生命周期是由spring容器管理的。

2、这就需要用到spring为我们提供的WebApplicationContextUtils工具类,该工具类的作用是获取到spring容器的引用,进而获取到我们需要的bean实例。

如:ChartLlmService chartLlmService = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext()).getBean(ChartLlmService.class);

3、把service的引用作为参数传给RankTask(),就可以用这个service进行调用了。

最后

以上就是孝顺糖豆为你收集整理的spring的TimerTask注入service为空的解决办法之一的全部内容,希望文章能够帮你解决spring的TimerTask注入service为空的解决办法之一所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(56)

评论列表共有 0 条评论

立即
投稿
返回
顶部