需求:在tomcat启动时开启一个定时任务。

想法:容器启动时执行方法,最容易想到的就是servlet中可以配置load-on-startup,设置一个正整数也就可以随容器一起启动。

问题:上面的方法很好,但是由于定时任务需要去操作数据库,而项目采用了spring的依赖注入来管理对象,而servlet并不受Spring的管理。若此时在servlet中注入Spring管理的对象,则会报错:javax.naming.NameNotFoundException: Name com.test.InitServlet is not bound in this Context。

所以想要再servlet中操作数据库,只能手动去创建一个service,这显然违背了我们使用Spring的初衷,让项目看起来不伦不类的。那么如何才能在启动WEB容器的时候执行一段初始化代码,并且可以让其被Spring管理呢?

解决方案:Spring提供了当一个Bean初始化后执行方法的扩展点:InitializingBean。这里的初始化指的就是当该Bean的属性被注入完成后(注意:这里并不是所有属性都需要被设置),所以InitializingBean接口提供的方法名称也很形象:afterPropertiesSet()。

使用的时,将该Bean注入到Spring容器,之后我们便可以获得Spring容器中的对象了,也就是说,可以得到service方法来执行我们的定时任务了。

具体代码如下:

[java] view plain copy
  1. @Component
  2. public class InitServlet implements InitializingBean {
  3. /**
  4. *
  5. */
  6. private static final long serialVersionUID = 1L;
  7. @Resource
  8. private DispatchesService dispatchesService;
  9. @Override
  10. public void afterPropertiesSet() throws Exception {
  11. dispatchesService.spyDDetails();
  12. }
  13. }

另外还有两种方法也可以实现如上的功能。

1、若采用XML来配置Bean的话,可以指定属性init-method

2、通过注解@PostConstruct来修改初始化方法

值得注意的是,三者可以同时存在,触发的顺序是先触发@PostConstruct修饰的方法,再触发afterPropertiesSet(),最后触发init-method

其中@PostConstruct是通过注册一个BeanPostProcessor,在Bean的初始化方法之前调用,而afterPropertiesSet()和init-method都在初始化方法中调用

关于@PostConstruct详细的介绍可以看这里:http://blog.csdn.net/yaerfeng/article/details/8447530

下面是Spring中调用Bean的初始化代码的源代码:

[java] view plain copy
  1. protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
  2. throws Throwable {
  3. boolean isInitializingBean = (bean instanceof InitializingBean);
  4. if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
  5. if (logger.isDebugEnabled()) {
  6. logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
  7. }
  8. if (System.getSecurityManager() != null) {
  9. try {
  10. AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
  11. public Object run() throws Exception {
  12. ((InitializingBean) bean).afterPropertiesSet();// 这里触发afterPropertiesSet
  13. return null;
  14. }
  15. }, getAccessControlContext());
  16. }
  17. catch (PrivilegedActionException pae) {
  18. throw pae.getException();
  19. }
  20. }
  21. else {
  22. ((InitializingBean) bean).afterPropertiesSet();// 这里触发afterPropertiesSet
  23. }
  24. }
  25. if (mbd != null) {
  26. String initMethodName = mbd.getInitMethodName();// 这里是触发init-method
  27. if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
  28. !mbd.isExternallyManagedInitMethod(initMethodName)) {
  29. invokeCustomInitMethod(beanName, bean, mbd);
  30. }
  31. }
  32. }

补充:

还有一种方法,是当Spring将所有的Bean都初始化完成后,会留给我们一个入口,我们可以实现如下接口

[java] view plain copy
  1. @Component
  2. public class InstantiationTracingBeanPostProcessor implements
  3. ApplicationListener<ContextRefreshedEvent> {
  4. @Override
  5. public void onApplicationEvent(ContextRefreshedEvent arg0) {
  6. System.out.println("-----所有Bean载入完成---");
  7. }
  8. }

Spring在Web容器启动时执行初始化方法的更多相关文章

  1. spring 在web容器启动时执行初始化方法

    开发框架:spingMVC+myBatis 解决方案:给web容器添加一个Listener类,在容器启动的时候执行Listener的“初始化”方法,在这个初始化方法中执行查询数据库的所有操作,然后将数 ...

  2. 在web项目启动时执行某个方法

    在web项目中有很多时候需要在项目启动时就执行一些方法,而且只需要执行一次,比如:加载解析自定义的配置文件.初始化数据库信息等等,在项目启动时就直接执行一些方法,可以减少很多繁琐的操作. 在工作中遇到 ...

  3. Spring项目启动时执行初始化方法

    一.applicationContext.xml配置bean <bean id="sensitiveWordInitUtil" class ="com.hx.daz ...

  4. Spring Boot学习--项目启动时执行特定方法

    Springboot给我们提供了两种"开机启动"某些方法的方式:ApplicationRunner和CommandLineRunner. 这两种方法提供的目的是为了满足,在项目启动 ...

  5. 转载:如何让spring mvc web应用启动时就执行

    转载:如何让spring mvc web应用启动时就执行特定处理 http://www.cnblogs.com/yjmyzz/p/4747251.html# Spring-MVC的应用中 一.Appl ...

  6. spring mvc web应用启动时就执行特定处理(线程启动)

    package com.sdt.platform.index.controller; import java.net.URL; import java.util.List; import java.u ...

  7. Web容器启动中执行某个Java类

    1.监听(Listener) <!-- 配置监听 --> <listener> <listener-class>com.xian.jdbc.GetPropertie ...

  8. spring boot, 容器启动后执行某操作

    常有在spring容器启动后执行某些操作的需求,现做了一个demo的实现,做一下记录,也希望可以给需要的同学提供参考. 1.spring启动后,以新线程执行后续需要的操作,所以执行类实现Runnabl ...

  9. spring注解之@PostConstruct在项目启动时执行指定方法

    一.注解解释 Spring的@PostConstruct注解在方法上,表示此方法是在Spring实例化该Bean之后马上执行此方法,之后才会去实例化其他Bean,并且一个Bean中@PostConst ...

随机推荐

  1. Scapy之ARP询问

    引言 校园网中,有同学遭受永恒之蓝攻击,但是被杀毒软件查下,并知道了攻击者的ip也是校园网.所以我想看一下,这个ip是PC,还是路由器. 在ip视角,路由器和pc没什么差别. 实现 首先是构造arp报 ...

  2. POJ 2151 Check the difficulty of problems 概率dp+01背包

    题目链接: http://poj.org/problem?id=2151 Check the difficulty of problems Time Limit: 2000MSMemory Limit ...

  3. 在数组中找出两数之和为10的所有组合(JAVA)

    /*利用冒泡排序实现*/ import java.util.Scanner;public class Paixun { public static void main(String[] args) { ...

  4. 第二章 Socket用法详解

    构造Socket Socket构造方法如下: Socket() //Creates an unconnected socket, with the system-default type of Soc ...

  5. Beta阶段团队项目开发篇章3

    例会时间 2016.12.6晚 例会照片 个人工作 上阶段任务验收 中英文切换功能已经实现,调查结果分析已经完成,博客基本撰写完成,在征求其他组员意见后发布.任务基本完成. 任务分配 组员 任务内容 ...

  6. Excel中用REPT函数制作图表

    本文从以下七个方面,阐述在Excel中用REPT函数制作图表: 一. 图形效果展示 二. REPT语法解释 三. REPT制作条形图 四. REPT制作漏斗图 五. REPT制作蝴蝶图 六. REPT ...

  7. zookeeper如何实现负载均衡的?(具体连接哪一个zookeeper服务器的选择?)阿里面试

    如果想了解web 6大负载均衡算法,参考:六大Web负载均衡原理与实现 主要是三点:负载均衡算法,健康检查和会话保持 1:首先,我们要了解,我们的应用程序,比如java web程序,里面配置了10个z ...

  8. VLD 无法打印堆栈调用情况

    调试时遇到了一个比较郁闷的问题:同样一个MFC工程,复制之后无任何附加操作,VLD便无法正常打印内存泄漏处的堆栈调用了 百度了一下,重要找到了答案:“VLD不支持中文” 复制工程时windows自动在 ...

  9. 第216天:Angular---自定义指令(二)

    自定义指令 1.第一个参数是指令的名字,第二个参数任然应该使用一个数组,数组的最后一个元素是一个函数.定义指令的名字,应该使用驼峰命名法 <!DOCTYPE html> <html ...

  10. NOIP2018前的一些计划&记录(日更)

    先空着,等停课了再开始写. 诸位好,我是yyb.现在显然已经不再是高一的小蒟蒻了,已经升级为了高二的菜鸡了 现在已经不能再每天划划水切切题了,毕竟......已经高二了,所有的机会从高一的两倍全部除了 ...