昨天遇到这个问题,在项目启动的时候添加一个定时器隔一段时间扫描有没有定时发送的邮件(当然也可以是你自己的业务逻辑),也在网上找了资料,加上自己的修改,终于成功了。所以来做个记录。

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容器初始化的时候如何添加一个定时器?的更多相关文章

  1. spring容器初始化执行某个方法

    在做web项目开发中,尤其是企业级应用开发的时候,往往会在工程启动的时候做许多的前置检查. 比如检查是否使用了我们组禁止使用的Mysql的group_concat函数,如果使用了项目就不能启动,并指出 ...

  2. 当spring 容器初始化完成后执行某个方法

    在做web项目开发中,尤其是企业级应用开发的时候,往往会在工程启动的时候做许多的前置检查. 比如检查是否使用了我们组禁止使用的Mysql的group_concat函数,如果使用了项目就不能启动,并指出 ...

  3. 当spring 容器初始化完成后执行某个方法 防止onApplicationEvent方法被执行两次

    在做web项目开发中,尤其是企业级应用开发的时候,往往会在工程启动的时候做许多的前置检查. 比如检查是否使用了我们组禁止使用的Mysql的group_concat函数,如果使用了项目就不能启动,并指出 ...

  4. 【sping揭秘】3、Spring容器中bean默认是保持一个实例

    Spring容器中bean默认是保持一个实例 这里做一个测试,基础代码 package cn.cutter.start.provider; import org.springframework.con ...

  5. spring容器初始化bean和销毁bean之前进行一些操作的定义方法

    关于在spring  容器初始化 bean 和销毁前所做的操作定义方式有三种:        第一种,通过在xml中定义init-method和destory-method方法        第二种, ...

  6. 【Spring实战】Spring容器初始化完成后执行初始化数据方法

    一.背景知识及需求 在做WEB项目时,经常在项目第一次启动时利用WEB容器的监听.Servlet加载初始化等切入点为数据库准备数据,这些初始化数据是系统开始运行前必须的数据,例如权限组.系统选项.默认 ...

  7. Spring容器初始化数据(数据库)BeanPostProcessor的应用

    1.目的:在Spring启动的时候加载在数据库保存的配置信息,一方面杜绝随意修改,一方面方便管理 2.BeanPostProcessor是Spring提供的一个方法通过implements方式实现 会 ...

  8. ApplicationListener接口,在spring容器初始化后执行的方法

    一.如果我们希望在Spring容器将所有的Bean都初始化完成之后,做一些操作,那么就可以使用ApplicationListener接口,实现ApplicationListener接口中的onAppl ...

  9. Spring容器初始化过程

    一.Spring 容器高层视图 Spring 启动时读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相应的Bean配置注册表,然后根据这张注册表实例化Bean,装配号Bean之间的依 ...

随机推荐

  1. Archive将多个对象归档到同一个文件

    使用archiveRootObject:toFile:方法能够将一个对象直接写入到一个文件里.但有时候可能想将多个对象写入到同一个文件里,那么就要使用NSData来进行归档对象. NSData能够为一 ...

  2. 修改System.Web.Mvc.WebViewPage创建自己的pageBase

    <system.web.webPages.razor> <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, ...

  3. Android架构须知

    1.了解不同版本号的特性包含IDE的. 如:AsyncTask3.0之后和之前的差别.Android 5.0的新的API.Android 6.0 不能用HttpClient .AS2.0的新特性 等等 ...

  4. Atitit.ati dwr的原理and设计 attilax 总结 java php 版本

    Atitit.ati dwr的原理and设计 attilax 总结 java php 版本 1. dwr的优点相对于ajax来说..1 2. DWR工作原理1 3. Dwr的架构2 4. 自定义dwr ...

  5. WebView中input file的解决方法

    public class MyWb extends Activity { /** Called when the activity is first created. */ WebView web; ...

  6. JSON学习【转自慕课网】

    视频网址 从慕课网视频里的PPT截图过来的,因为是用PHP讲的,而且后面讲的一般,所以只截取了前两节课的基础内容,其实只看一下第一张PPT就可以了.

  7. eclipse不自动弹出提示的解决办法(eclipse alt+/快捷键失效)centos 6.7

    1.次方法用于没有一点提示的情况:依次打开eclipse上面的windows ——preferences ——java ——editor —— content assist ,在右上方有一行“sele ...

  8. 转载:JMeter压力测试入门教程[图文]

    JMeter压力测试入门教程[图文] Apache JMeter是Apache组织开发的基于Java的压力测试工具.用于对软件做压力测试,它最初被设计用于Web应用测试但后来扩展到其他测试领域. 它可 ...

  9. I/O的控制方式——查询,中断,dma(转)

    早期,I/O串行,查询方式.发展,I/O并行,两种方式其一是中断方式,其二是dma方式,使得外部设备能直接与主存储器信息交换,减轻了cpu的工作量.技术继续发展,出现通道结构,实质上为高性能的dma控 ...

  10. jquery mobile demo

    <!DOCTYPE html> <html> <head> <title>jQuery Mobile Demo</title> <me ...