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的更多相关文章

  1. atititt.java定时任务框架选型Spring Quartz 注解总结

    atititt.java定时任务框架选型Spring Quartz 总结 1. .Spring Quartz  (ati recomm) 1 2. Spring Quartz具体配置 2 2.1. 增 ...

  2. 如何在自定义Listener(监听器)中使用Spring容器管理的bean

    正好以前项目中碰到这个问题,现在网上偶然又看到这个问题的博文,那就转一下吧. 原文:http://blog.lifw.org/post/46428852 感谢作者 另外补充下:在web Server容 ...

  3. quartz 框架定时任务,使用spring @Scheduled注解执行定时任务

    配置quartz 在spring中需要三个jar包: quartz-1.6.5.jar.commons-collections-3.2.jar.commons-logging-1.1.jar 首先要配 ...

  4. 服务器启动完成执行定时任务Timer,TimerTask

    由于项目需求:每隔一段时间就要调外部接口去进行某些操作,于是在网上找了一些资料,用了半天时间弄好了,代码: import java.util.TimerTask; public class Accou ...

  5. Listener监听器和Filter过滤器

    Listener监听器 WEB中的监听器 WEB 中的 Listener 和 Filter 是属于 Servlet 规范中的高级的技术.WEB中的监听器共有三类八种(监听三个域对象)* 事件源:Ser ...

  6. TimerTask定时任务

    web.xml <listener> <listener-class>com.sign.listener.NFDFlightDataTaskListener</liste ...

  7. [Java] JSP笔记 - Listener 监听器

    Java Web 开发时,可以使用 Listener 来监听来监听一些事件,从而实现一些功能.实际上这个监听器,原理就是 Delphi 中大家常用的各种事件. 1. 那么,监听器的主要用途用哪些呢: ...

  8. listener监听器的相关知识

    从别人的博客上我学习了listener的相关知识现在分享给大家 1.概念: 监听器就是一个实现特定接口的普通java程序,这个程序专门用于监听另一个java对象的方法调用或属性改变,当被监听对象发生上 ...

  9. listener监听器

    前言:之前写了一篇关于Filter的文章:http://tianweili.github.io/blog/2015/01/26/java-filter/,现在再来一篇Listener的,Filter和 ...

随机推荐

  1. Logistic Regression总结

    转自:http://blog.csdn.net/dongtingzhizi/article/details/15962797 Logistic回归总结 作者:洞庭之子 微博:洞庭之子-Bing (20 ...

  2. Intent 简介 结构 传递数据 常见Action 常量 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  3. AS 功能 设置 SDK AVD 简介 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  4. Hibernate缓存应用的积累与总结

    Hibernate缓存一直比较难掌握,下面就分析和总结原因,相信你就会慢慢清楚了原来Hibernate缓存也是可以轻松掌握的,但前提要求大家必须跟着动手去验证一下,再用心体会,光看是没有用的 目录: ...

  5. python3 中对arrow库的总结(转发)

    https://blog.csdn.net/soft_kind/article/details/80614896 arrow库的官方文档:http://arrow.readthedocs.io/en/ ...

  6. Android模仿三星手机系统滑动条滑动时滑块变大的特效

    使用三星手机的过程中发现三星手机系统自带的滑动条有一个特效.比方调节亮度的滑动条.在滑动滑块的过程中,滑块会变大.功能非常小可是体验却非常好,于是决定做一个这种效果出来.好了废话不多说了,以下開始实现 ...

  7. cmake 学习笔记(三) (转)

    接前面的 Cmake学习笔记(一) 与 Cmake学习笔记(二) 继续学习 cmake 的使用. 学习一下cmake的 finder. finder是神马东西? 当编译一个需要使用第三方库的软件时,我 ...

  8. Asp.net MVC利用WebUploader上传大文件出现404解决办法。

    刚开始我上传小文件都是比较顺利的,但是上传了一个大文件大约有200M的压缩包就不行了.在chrome里面监视发现网络状态是404,我分析可能不是WebUploader的限制,应该是WebConfig限 ...

  9. [Canvas]New Running Dog

    欲看效果请下载后用Chrome浏览器打开index.html观看,下载地址:https://files.cnblogs.com/files/xiandedanteng/51-NewRunningDog ...

  10. 详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点

    转自:http://www.jb51.net/article/100111.htm 首先我们需要安装好Nginx.jdk.Tomcat,安装方法已经在 上一篇 说过了,本篇不再赘述. 下来看一下我们的 ...