Spring容器初始化的时候如何添加一个定时器?
昨天遇到这个问题,在项目启动的时候添加一个定时器隔一段时间扫描有没有定时发送的邮件(当然也可以是你自己的业务逻辑),也在网上找了资料,加上自己的修改,终于成功了。所以来做个记录。
1、ServletContextListener
我们需要在web容器启动的时候,就添加自己的业务。那么有没有一个类或接口能监听web容器的生命周期呢?当然是有的,在Servlet API 中有一个 ServletContextListener 接口,它能够监听 ServletContext 对象的生命周期,也就满足我们的要求。
2、WebApplicationContext
ApplicationContext是Spring的核心,Context我们通常解释为上下文环境,我想用“容器”来表述它更容易理解一些,ApplicationContext则是“应用的容器”了;在Web应用中,我们会用到WebApplicationContext,WebApplicationContext继承自ApplicationContext;WebApplicationContext的初始化方式和BeanFactory.ApplicationContext有所区别,因为WebApplicationContext需要ServletContext实例,也就是说它必须拥有Web容器的前提下才能完成启动的工作。
3、Java代码:
package com.defer.mail.util; import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.defer.mail.domain.Email;
import com.defer.mail.domain.User;
import com.defer.mail.service.EmailService;
import com.defer.mail.service.UserService;
public class SendEmailTimer implements ServletContextListener{ private Timer timer = null; /**
* @Name: contextInitialized
* @Description:容器初始化
**/
@Override
public void contextInitialized(ServletContextEvent event) {
//通过给spring的WebApplicationContextUtils传入ServletContext的监听对象来获取获取当前的web容器
WebApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(event.getServletContext());
//创建定时器
timer = new Timer(true);
System.out.println("定时器已经启动");
//设定每7200秒查询一次是否有定时发送邮件
timer.schedule(new QuerySendEmail(ac), 0, 7200*1000);
System.out.println("已经添加查询任务");
} /**
* ClassName: QuerySendEmail
* @Description: 业务类,继承TimerTask类,添加自己的业务
*/
private static class QuerySendEmail extends TimerTask {
private static boolean isRunning = false;
private WebApplicationContext context = null; public QuerySendEmail(WebApplicationContext context) {
this.context = context;
} @SuppressWarnings("static-access")
@Override
public void run() {
if(!isRunning) {
isRunning = true;
// TODO 自己的业务流程
EmailService emailService = (EmailService) context.getBean("emailServiceImpl");
UserService userService = (UserService) context.getBean("userServiceImpl");
List<Email> emailList = emailService.findNoSendEmail();
if(emailList != null && emailList.size() >0) {
for (Email email : emailList) {
User user = userService.getById(email.getUser().getId());
String fromUser = user.getEmail();
String code = email.getCode();
String topic = email.getTopic();
String content = email.getContent();
String toUser = email.getToUser();
SendEmail sendEmail = new SendEmail();
boolean status = false;
while(status==false) { status = sendEmail.sendEmail(fromUser, toUser, code, topic, content);
if(status) {
email.setStatus("1"); //设置邮件状态为已发送
email.setSendDate(new Date()); //设置发送时间
emailService.update(email);
status = true;
System.out.println("发送成功=========");
} else {
status = false;
System.out.println("发送失败=========");
} }
}
} else {
System.out.println("没有定时邮件");
} isRunning = false;
System.out.println("查询结束");
} else {
System.out.println("上一次查询还未结束");
} } } /**
*
* @Name: contextDestroyed
* @Description:容器销毁
*/
@Override
public void contextDestroyed(ServletContextEvent servletcontextevent) {
// TODO Auto-generated method stub } }
4、虽然该类实现了ServletContextListener接口,如何让spring容器加载的时候能初始化该类中的操作呢?那肯定少不了配置spring的配置文件
<!-- 用于定时器工作的监听器。配置在spring的ContextLoaderListener之后,因为需要用到spring的容器对象 -->
<listener>
<listener-class>
<!-- 自己的类路径 -->
com.defer.mail.util.SendEmailTimer
</listener-class>
</listener>
5、测试成功

Spring容器初始化的时候如何添加一个定时器?的更多相关文章
- spring容器初始化执行某个方法
在做web项目开发中,尤其是企业级应用开发的时候,往往会在工程启动的时候做许多的前置检查. 比如检查是否使用了我们组禁止使用的Mysql的group_concat函数,如果使用了项目就不能启动,并指出 ...
- 当spring 容器初始化完成后执行某个方法
在做web项目开发中,尤其是企业级应用开发的时候,往往会在工程启动的时候做许多的前置检查. 比如检查是否使用了我们组禁止使用的Mysql的group_concat函数,如果使用了项目就不能启动,并指出 ...
- 当spring 容器初始化完成后执行某个方法 防止onApplicationEvent方法被执行两次
在做web项目开发中,尤其是企业级应用开发的时候,往往会在工程启动的时候做许多的前置检查. 比如检查是否使用了我们组禁止使用的Mysql的group_concat函数,如果使用了项目就不能启动,并指出 ...
- 【sping揭秘】3、Spring容器中bean默认是保持一个实例
Spring容器中bean默认是保持一个实例 这里做一个测试,基础代码 package cn.cutter.start.provider; import org.springframework.con ...
- spring容器初始化bean和销毁bean之前进行一些操作的定义方法
关于在spring 容器初始化 bean 和销毁前所做的操作定义方式有三种: 第一种,通过在xml中定义init-method和destory-method方法 第二种, ...
- 【Spring实战】Spring容器初始化完成后执行初始化数据方法
一.背景知识及需求 在做WEB项目时,经常在项目第一次启动时利用WEB容器的监听.Servlet加载初始化等切入点为数据库准备数据,这些初始化数据是系统开始运行前必须的数据,例如权限组.系统选项.默认 ...
- Spring容器初始化数据(数据库)BeanPostProcessor的应用
1.目的:在Spring启动的时候加载在数据库保存的配置信息,一方面杜绝随意修改,一方面方便管理 2.BeanPostProcessor是Spring提供的一个方法通过implements方式实现 会 ...
- ApplicationListener接口,在spring容器初始化后执行的方法
一.如果我们希望在Spring容器将所有的Bean都初始化完成之后,做一些操作,那么就可以使用ApplicationListener接口,实现ApplicationListener接口中的onAppl ...
- Spring容器初始化过程
一.Spring 容器高层视图 Spring 启动时读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相应的Bean配置注册表,然后根据这张注册表实例化Bean,装配号Bean之间的依 ...
随机推荐
- 盘点SEO和SEM的优劣势
如果你不知如何分配你的搜索营销预算,或是和客户提案的时候不知道怎么样去解释搜索营销产品(SEO和SEM)的区别,又或者不了解网站/企业在当前阶段应该优先施行哪种搜索营销策略,本文可以帮助你深入了解SE ...
- 函数参数中“x++”造成的运算无效测试
可能以前书上都有说过,当时没在意 只有在实际项目中才会遇到因这个问题导致的Bug 2017/2/26日补充:实际上比较通用的做法是 ++tmp1,这样也可以做到自增 ; ); Console.Writ ...
- FPGA的图像处理技术
最近一段时间一直在研究基于FPGA的图像处理,乘着EEPW这个机会和大家交流一下,自己也顺便总结一下.主要是为了大家对用FPGA做图像处理有个感性的认识,如果真要研究的话就得更加深入学习了.本人水平有 ...
- tensorflow 之模型的保存与加载(一)
怎样让通过训练的神经网络模型得以复用? 本文先介绍简单的模型保存与加载的方法,后续文章再慢慢深入解读. #!/usr/bin/env python3 #-*- coding:utf-8 -*- ### ...
- Hello,Ajax
学习了Ajax技术,写了一个最简单的Ajax应用 <%@page contentType="text/html; charset=utf-8" language=" ...
- SQL Server DTS向导,字段转换出现202和200错误
当使用SQL Server 2012的DTS向导(Import and Export Data/导入导出数据)时,会出现如下问题: 当来源数据直接使用表的时候,没有任何问题 但如果来源数据是查询时,就 ...
- CentOS平滑升级Nginx
服务器:CentOS 6.4 64位 升级方案:nginx1.4.0 – nginx1.4.3 Nginx编译后就一个小文件,不带动态库,升级也可以无缝升级,并不影响访问,按下面的命令执行就可以,具体 ...
- Chrome调试ECMAScript之断点debug技巧大全!
这篇文章主要介绍了使用Chrome调试JavaScript的断点设置和调试技巧,需要的朋友可以参考下 你是怎么调试 JavaScript 程序的?最原始的方法是用 alert() 在页面上打印内容,稍 ...
- ASP.NET中26种性能优化方法
系统类 Type类,Object类,String类, Arrary类,Console类, Exception类,GC类, MarshalByRefObject类, Math类. DateTime结构 ...
- C语言 函数指针一(函数指针的定义)
//函数指针 #include<stdio.h> #include<stdlib.h> #include<string.h> //函数指针类型跟数组类型非常相似 / ...