在Listener(监听器)定时启动的TimerTask(定时任务)中使用Spring@Service注解的bean
1.有时候在项目中需要定时启动某个任务,对于这个需求,基于JavaEE规范,我们可以使用Listener与TimerTask来实现,代码如下:
public class TestTaskListener implements ServletContextListener {
//Context()初始化方法
@Override
public void contextInitialized(ServletContextEvent sce) {
//新建一个定时管理器
new TestTimerManager();
}
public TestTaskListener() {
super();
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
2.contextInitialized方法中新建了一个定时管理器,代码如下:
public class TestTimerManager {
//新建一个定时器
Timer timer = new Timer();
public TestTimerManager() {
super();
//新建一个定时任务
TestTimerTask task = new TestTimerTask();
//设置定时任务
timer.schedule(task, firstTimeToStartTheTask, period);
}
}
3.在定时任务的Constructor中新建了一个定时任务,其代码如下:
@Configuration
public class TestTimerTask extends TimerTask {
//采用Spring框架的依赖注入
@Autowired
private SelectDataService selectDataService; public TestTimerTask() {
super();
}
@Override
public void run(){
try {
//访问数据库
MyData myData = selectDataService.selectMyDataById(id);
}catch(Exception ex) {
System.out.println("定时任务出错");
ex.printStackTrace();
}
}
}
spring是个性能非常优秀的抽象工厂,可以生产出工程所需要的实例,这里采用Spring容器的自动注入selectDataService实例。上面代码中,selectDataService这个类是采用Spring的@Service注解的,在项目中主要通过Spring容器注入到Controller中,其作用主要用来访问数据库。
运行项目将会发现NullPointerException,也就是说SelectDataService的实例没有被注入到变量selectDataService中。那么,这是什么原因呢?首先来看看配置文件。
下面是web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.test.TestTaskListener</listener-class>
</listener>
在启动web项目时,Servlet容器(比如Tomcat)会读web.xml配置文件中的两个节点和,节点用来加载appliactionContext.xml(即Spring的配置文件),节点用来创建监听器(比如TestTaskListener)实例。Listener的生命周期是由servlet容器管理的,例中的TestTaskListener是由servlet容器实例化并调用其contextInitialized方法的,但是,SelectDataService是通过@Service注解的,也就是说SelectDataService是由Spring容器管理的,在Spring容器外无法直接通过依赖注入得到Spring容器管理的bean实例的引用。为了在Spring容器外得到Spring容器管理的bean,可以使用Spring提供的工具类WebApplicationContextUtils。也就是说,可以在servlet容器管理的Listener中使用该工具类获Spring管理的bean。
看如下代码:
public class TestTaskListener implements ServletContextListener {
//Context()初始化方法
@Override
public void contextInitialized(ServletContextEvent sce) {
//获得Spring容器
WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
//从Spring容器中获得SelectDataServlet的实例
SelectDataService selectDataService = ctx.getBean(SelectDataService.class);
//新建一个定时管理器
new TestTimerManager();
}
public TestTaskListener() {
super();
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
那么在Listener中获得的SelectDataService实例如何在TestTimerTask中使用呢?可以通过作为参数传递过去,看如下代码:
public class TestTaskListener implements ServletContextListener {
//Context()初始化方法
@Override
public void contextInitialized(ServletContextEvent sce) {
//获得Spring容器
WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
//从Spring容器中获得SelectDataServlet的实例
SelectDataService selectDataService = ctx.getBean(SelectDataService.class);
//新建一个定时管理器
new TestTimerManager(selectDataService);
}
public TestTaskListener() {
super();
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
public class TestTimerManager {
//新建一个定时器
Timer timer = new Timer();
public TestTimerManager(SelectDataService selectDataService) {
super();
//新建一个定时任务
TestTimerTask task = new TestTimerTask(selectDataService);
//设置定时任务
timer.schedule(task, firstTimeToStartTheTask, period);
}
}
@Configuration
public class TestTimerTask extends TimerTask {
private SelectDataService selectDataService;
public TestTimerTask(SelectDataService selectDataService) {
super();
this.selectDataService = selectDataService;
}
@Override
public void run(){
try {
//访问数据库
MyData myData = selectDataService.selectMyDataById(id);
}catch(Exception ex) {
System.out.println("定时任务出错");
ex.printStackTrace();
}
}
}
再回到web.xml
由于Servlet容器在初始化TestTaskListener时,获取了Spring容器,所以必须保证,在此之前,Spring容器已经初始化完成。因为Spring容器的初始化也是由Listener(ContextLoaderListener)完成,该监听器用Spring框架提供,可以在web应用启动时启动Spring容器。所以,在web.xml中,要先配置ContextLoaderListener,再配置TestTaskListener。
1.有时候在项目中需要定时启动某个任务,对于这个需求,基于JavaEE规范,我们可以使用Listener与TimerTask来实现,代码如下:
public class TestTaskListener implements ServletContextListener {
//Context()初始化方法
@Override
public void contextInitialized(ServletContextEvent sce) {
//新建一个定时管理器
new TestTimerManager();
}
public TestTaskListener() {
super();
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
2.contextInitialized方法中新建了一个定时管理器,代码如下:
public class TestTimerManager {
//新建一个定时器
Timer timer = new Timer();
public TestTimerManager() {
super();
//新建一个定时任务
TestTimerTask task = new TestTimerTask();
//设置定时任务
timer.schedule(task, firstTimeToStartTheTask, period);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
3.在定时任务的Constructor中新建了一个定时任务,其代码如下:
@Configuration
public class TestTimerTask extends TimerTask {
//采用Spring框架的依赖注入
@Autowired
private SelectDataService selectDataService;
public TestTimerTask() {
super();
}
@Override
public void run(){
try {
//访问数据库
MyData myData = selectDataService.selectMyDataById(id);
}catch(Exception ex) {
System.out.println("定时任务出错");
ex.printStackTrace();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
spring是个性能非常优秀的抽象工厂,可以生产出工程所需要的实例,这里采用Spring容器的自动注入selectDataService实例。上面代码中,selectDataService这个类是采用Spring的@Service注解的,在项目中主要通过Spring容器注入到Controller中,其作用主要用来访问数据库。
运行项目将会发现NullPointerException,也就是说SelectDataService的实例没有被注入到变量selectDataService中。那么,这是什么原因呢?首先来看看配置文件。
下面是web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.test.TestTaskListener</listener-class>
</listener>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
在启动web项目时,Servlet容器(比如Tomcat)会读web.xml配置文件中的两个节点和,节点用来加载appliactionContext.xml(即Spring的配置文件),节点用来创建监听器(比如TestTaskListener)实例。Listener的生命周期是由servlet容器管理的,例中的TestTaskListener是由servlet容器实例化并调用其contextInitialized方法的,但是,SelectDataService是通过@Service注解的,也就是说SelectDataService是由Spring容器管理的,在Spring容器外无法直接通过依赖注入得到Spring容器管理的bean实例的引用。为了在Spring容器外得到Spring容器管理的bean,可以使用Spring提供的工具类WebApplicationContextUtils。也就是说,可以在servlet容器管理的Listener中使用该工具类获Spring管理的bean。
看如下代码:
public class TestTaskListener implements ServletContextListener {
//Context()初始化方法
@Override
public void contextInitialized(ServletContextEvent sce) {
//获得Spring容器
WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
//从Spring容器中获得SelectDataServlet的实例
SelectDataService selectDataService = ctx.getBean(SelectDataService.class);
//新建一个定时管理器
new TestTimerManager();
}
public TestTaskListener() {
super();
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
那么在Listener中获得的SelectDataService实例如何在TestTimerTask中使用呢?可以通过作为参数传递过去,看如下代码:
public class TestTaskListener implements ServletContextListener {
//Context()初始化方法
@Override
public void contextInitialized(ServletContextEvent sce) {
//获得Spring容器
WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
//从Spring容器中获得SelectDataServlet的实例
SelectDataService selectDataService = ctx.getBean(SelectDataService.class);
//新建一个定时管理器
new TestTimerManager(selectDataService);
}
public TestTaskListener() {
super();
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
public class TestTimerManager {
//新建一个定时器
Timer timer = new Timer();
public TestTimerManager(SelectDataService selectDataService) {
super();
//新建一个定时任务
TestTimerTask task = new TestTimerTask(selectDataService);
//设置定时任务
timer.schedule(task, firstTimeToStartTheTask, period);
}
}
@Configuration
public class TestTimerTask extends TimerTask {
private SelectDataService selectDataService;
public TestTimerTask(SelectDataService selectDataService) {
super();
this.selectDataService = selectDataService;
}
@Override
public void run(){
try {
//访问数据库
MyData myData = selectDataService.selectMyDataById(id);
}catch(Exception ex) {
System.out.println("定时任务出错");
ex.printStackTrace();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
再回到web.xml
由于Servlet容器在初始化TestTaskListener时,获取了Spring容器,所以必须保证,在此之前,Spring容器已经初始化完成。因为Spring容器的初始化也是由Listener(ContextLoaderListener)完成,该监听器用Spring框架提供,可以在web应用启动时启动Spring容器。所以,在web.xml中,要先配置ContextLoaderListener,再配置TestTaskListener。
在Listener(监听器)定时启动的TimerTask(定时任务)中使用Spring@Service注解的bean的更多相关文章
- atititt.java定时任务框架选型Spring Quartz 注解总结
atititt.java定时任务框架选型Spring Quartz 总结 1. .Spring Quartz (ati recomm) 1 2. Spring Quartz具体配置 2 2.1. 增 ...
- 如何在自定义Listener(监听器)中使用Spring容器管理的bean
正好以前项目中碰到这个问题,现在网上偶然又看到这个问题的博文,那就转一下吧. 原文:http://blog.lifw.org/post/46428852 感谢作者 另外补充下:在web Server容 ...
- quartz 框架定时任务,使用spring @Scheduled注解执行定时任务
配置quartz 在spring中需要三个jar包: quartz-1.6.5.jar.commons-collections-3.2.jar.commons-logging-1.1.jar 首先要配 ...
- 服务器启动完成执行定时任务Timer,TimerTask
由于项目需求:每隔一段时间就要调外部接口去进行某些操作,于是在网上找了一些资料,用了半天时间弄好了,代码: import java.util.TimerTask; public class Accou ...
- Listener监听器和Filter过滤器
Listener监听器 WEB中的监听器 WEB 中的 Listener 和 Filter 是属于 Servlet 规范中的高级的技术.WEB中的监听器共有三类八种(监听三个域对象)* 事件源:Ser ...
- TimerTask定时任务
web.xml <listener> <listener-class>com.sign.listener.NFDFlightDataTaskListener</liste ...
- [Java] JSP笔记 - Listener 监听器
Java Web 开发时,可以使用 Listener 来监听来监听一些事件,从而实现一些功能.实际上这个监听器,原理就是 Delphi 中大家常用的各种事件. 1. 那么,监听器的主要用途用哪些呢: ...
- listener监听器的相关知识
从别人的博客上我学习了listener的相关知识现在分享给大家 1.概念: 监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上 ...
- listener监听器
前言:之前写了一篇关于Filter的文章:http://tianweili.github.io/blog/2015/01/26/java-filter/,现在再来一篇Listener的,Filter和 ...
随机推荐
- Visual Studio 2008 安装失败(“Web 创作组件”无法安装)(转)
今天安装VS2008时出现了问题,怎么都无法安装成功.装了好几次都在“Visual Studio Web 创作组件(Visual Studio Authoring Component)”的安装的时候失 ...
- 备份VMware虚拟磁盘文件 移植到其他虚拟机
原文:http://jingyan.baidu.com/article/a681b0de17b3173b1843468f.html 方法/步骤 第一种方法:直接复制本地主机磁盘下的虚拟磁盘文件 ...
- jQuery中的编程范式
浏览器前端编程的面貌自2005年以来已经发生了深刻的变化,这并不简单的意味着出现了大量功能丰富的基础库,使得我们可以更加方便的编写业务代码,更重要的是我们看待前端技术的观念发生了重大转变,明确意识到了 ...
- 汇总c#.net常用函数和方法集
1.DateTime 数字型 System.DateTime currentTime=new System.DateTime(); 1.1 取当前年月日时分秒 currentTime=System.D ...
- 转 :scikit-learn的GBDT工具进行特征选取。
http://blog.csdn.net/w5310335/article/details/48972587 使用GBDT选取特征 2015-03-31 本文介绍如何使用scikit-learn的GB ...
- 添加 jar 包后需要做的配置
- Java归去来第3集:Eclipse中给动态模块升级
一.前言 如果还不了解剧情,请返回第2集的剧情 Java归去来第2集:利用Eclipse创建Maven Web项目 二.开始升级动态模块 2.1:查看原来的版本 我们先来看看Ecli ...
- C#.NET常见问题(FAQ)-如何让TabControl可以动态增加或删除
动态插入可以使用TabPages.Insert方法 动态删除可以用Remove方法 更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: http://i.youku.com/aceta ...
- iOS编程(双语版) - 视图 - 基本概念
1. 什么是视图? 视图显示为手机上的一块矩形区域,管理该区域的所有屏幕显示,它是UIView或者UIView的子类. 视图既可以从xib生成,也可以用代码生成. 2. 窗口 窗口是UIWindow或 ...
- 微信小程序 - 自定义switch切换(示例)
点击下载:switch示例 ,适用于表单,官方switch 说明 .