zoukankan      html  css  js  c++  java
  • 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代码:

      1 package com.defer.mail.util;
      2 
      3 import java.util.Date;
      4 import java.util.List;
      5 import java.util.Timer;
      6 import java.util.TimerTask;
      7 import javax.servlet.ServletContextEvent;
      8 import javax.servlet.ServletContextListener;
      9 import org.springframework.web.context.WebApplicationContext;
     10 import org.springframework.web.context.support.WebApplicationContextUtils;
     11 import com.defer.mail.domain.Email;
     12 import com.defer.mail.domain.User;
     13 import com.defer.mail.service.EmailService;
     14 import com.defer.mail.service.UserService;
     15 public class SendEmailTimer implements ServletContextListener{
     16     
     17     
     18     private Timer timer = null;
     19 
     20     /**
     21      * @Name: contextInitialized
     22      * @Description:容器初始化
     23      **/
     24     @Override
     25     public void contextInitialized(ServletContextEvent event) {
     26         //通过给spring的WebApplicationContextUtils传入ServletContext的监听对象来获取获取当前的web容器
     27         WebApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(event.getServletContext());
     28         //创建定时器
     29         timer = new Timer(true);
     30         System.out.println("定时器已经启动");
     31         //设定每7200秒查询一次是否有定时发送邮件
     32         timer.schedule(new QuerySendEmail(ac), 0, 7200*1000);
     33         System.out.println("已经添加查询任务");
     34     }
     35     
     36     /**
     37      * ClassName: QuerySendEmail
     38      * @Description: 业务类,继承TimerTask类,添加自己的业务
     39      */
     40     private static class QuerySendEmail extends TimerTask {
     41         private static boolean isRunning = false;
     42         private WebApplicationContext context = null;
     43         
     44         public QuerySendEmail(WebApplicationContext context) {
     45             this.context = context;
     46         }
     47         
     48         @SuppressWarnings("static-access")
     49         @Override
     50         public void run() {
     51             if(!isRunning) {
     52                 isRunning = true;
     53                 // TODO 自己的业务流程
     54                 EmailService emailService = (EmailService) context.getBean("emailServiceImpl");
     55                 UserService userService = (UserService) context.getBean("userServiceImpl");
     56                 List<Email> emailList = emailService.findNoSendEmail();
     57                 if(emailList != null && emailList.size() >0) {
     58                     for (Email email : emailList) {
     59                         User user = userService.getById(email.getUser().getId());
     60                         String fromUser = user.getEmail();
     61                         String code = email.getCode();
     62                         String topic = email.getTopic();
     63                         String content = email.getContent();
     64                         String toUser = email.getToUser();
     65                         SendEmail sendEmail = new SendEmail();
     66                         boolean status = false;
     67                         while(status==false) {
     68                             
     69                             status = sendEmail.sendEmail(fromUser, toUser, code, topic, content);
     70                             if(status) {
     71                                 email.setStatus("1");    //设置邮件状态为已发送
     72                                 email.setSendDate(new Date());    //设置发送时间
     73                                 emailService.update(email);
     74                                 status = true;
     75                                 System.out.println("发送成功=========");
     76                             } else {
     77                                 status = false;
     78                                 System.out.println("发送失败=========");
     79                             }
     80                             
     81                         }
     82                     }
     83                 } else {
     84                     System.out.println("没有定时邮件");
     85                 }
     86                 
     87                 isRunning = false;
     88                 System.out.println("查询结束");
     89             } else {
     90                 System.out.println("上一次查询还未结束");
     91             }
     92             
     93         }
     94         
     95     }
     96     
     97     /**
     98      * 
     99      * @Name: contextDestroyed
    100      * @Description:容器销毁
    101      */
    102     @Override
    103     public void contextDestroyed(ServletContextEvent servletcontextevent) {
    104         // TODO Auto-generated method stub
    105         
    106     }
    107 
    108     
    109 }

    4、虽然该类实现了ServletContextListener接口,如何让spring容器加载的时候能初始化该类中的操作呢?那肯定少不了配置spring的配置文件

    1 <!-- 用于定时器工作的监听器。配置在spring的ContextLoaderListener之后,因为需要用到spring的容器对象 -->
    2 <listener>
    3         <listener-class>
    4             <!-- 自己的类路径 -->
    5             com.defer.mail.util.SendEmailTimer
    6         </listener-class>
    7 </listener>

    5、测试成功

  • 相关阅读:
    在国内时,更新ADT时需要配置的
    mantis增加密码修改
    http://182.92.241.20/mypro/login 偶的点金项目细化分包管理平台即将上线!!
    bootstrap菜单完美解决---原创
    PB常用日期
    ctrl+shift+del 清理火狐缓存,解决页面显示错乱问题
    Kylin上chromium不能用flash的解决命令
    正确的SVN导入代码命令
    GNU :6.47 Function Names as Strings
    std::advance 给迭代器增加指定偏移量
  • 原文地址:https://www.cnblogs.com/guxiong/p/6741920.html
Copyright © 2011-2022 走看看