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

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. STL 容器(vector 和 list )

    1.这个容器的知识点比较杂 迭代器的理解: 1.erase()函数的返回值,它的迭代器在循环遍历中的奇特之处: #define _CRT_SECURE_NO_WARNINGS #include < ...

  2. 企业信息系统集成框架(设计思路)C++模式

    设计要求: 1.企业信息系统框架.第三方产品通过接口层进行分层. 2.企业信息系统框架如何自由的继承第三方产品:通过一个抽象类.(软件设计要求:模块要求松,接口要求紧). 设计步骤: 1.报文的接受与 ...

  3. 算法----堆排序(heap sort)

    堆排序是利用堆进行排序的高效算法,其能实现O(NlogN)的排序时间复杂度,详细算法分析能够点击堆排序算法时间复杂度分析. 算法实现: 调整堆: void sort::sink(int* a, con ...

  4. access denied XXXXXXXXXXXX

    这个异常是做支付的时候出现的,貌似是没有权限访问之类的,网上查了有N个解决的办法,我写一下我解决的办法吧....... 出现的异常具体: java.security.AccessControlExce ...

  5. Memcache集群安装与配置

    Memcache集群的安装和配置 :http://blog.163.com/asd_wll/blog/static/210310402013084405481/

  6. 点滴积累【other】---Windows 7 IIS (HTTP Error 500.21 - Internal Server Error)解决方案(转载)

    此文来自:http://blog626.blog.163.com/blog/static/105610732201051591450870/ 搭建IIS时出现如下错误: HTTP Error 500. ...

  7. Atitit.jquery 版本新特性attilax总结

    Atitit.jquery 版本新特性attilax总结 1. Jq1.4 1 2. 1.5 1 3. 1.6 3 4. Jq1.7 3 ⒉提升了事件委派时的性能有了大幅度的提升,尤其是在ie7下: ...

  8. [na][win]系统优化工具dism++

    系统优化工具, 确实能将c盘扩大个2-3g. 主要是删除日志 优化系统等功能. https://www.chuyu.me/

  9. MySQL主从同步那点事儿

    一.前言 关于mysql主从同步,相信大家都不陌生,随着系统应用访问量逐渐增大,单台数据库读写访问压力也随之增大,当读写访问达到一定瓶颈时,将数据库的读写效率骤然下降,甚至不可用;为了解决此类问题,通 ...

  10. 反射学习1、反射机制的介绍和基本的API的使用

    关于动态语言: 一般而言,开发者社群说到动态语言,大致认同的一个定义是:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”.从这个观点看,Perl,Python,Ruby是动态语言,C+ ...