SpringMVC在启动完成后执行方法

来源:互联网 发布:python 粒子群算法包 编辑:程序博客网 时间:2024/06/05 22:50

2017/5/19 9:34:22 使用markdown重新编辑,并引入新的参考链接。
2017/10/26 19:58:49 修改格式.

第一个版本发布于 2017-02-08 23:23

通过实现ApplicationListener来达到在spring容器加载完毕时来作出某些自定义的操作,关于这一点想必很多人都知道了,本篇文档当然不会是这类被很多前人讲述了一遍又一遍的东西。

今天所要讲的是在SpringMVC中在上面实现的方法会被Spring回调两次,如果你是因为这个问题而找到了这篇文章,那么恭喜你达到了终点,在下面的内容里我会给出解决方案和产生这种现象的原因。

解决方案

不要在spring.xml中注册上面那个实现了ApplicationListener<ContextRefreshedEvent>接口的类,去在spring-mvc.xml中进行注册即可.

原因

我们一般会有spring.xmlspring-mvc.xml两个文件, 针对这两个文件.

  1. Spring里获取bean的逻辑是:如果在自身的容器中没有找到该对象,那么就去parent container中查找(相关源码参见AbstractBeanFactory类中的doGetBean方法–[(parentBeanFactory != null && !containsBeanDefinition(beanName))])
  2. 而Spring中的事件通知逻辑如下: 先向自身的容器发起事件通知,如果本容器有parent container存在,则在parent container进行一次通知(相关源码参见AbstractApplicationContext类中的publishEvent方法)
  3. 所以:
    1. parent container(spring.xml作为配置文件)
      ContextLoaderListener(org.springframework.web.context.ContextLoaderListener)载入
    2. child container(spring-mvc.xml作为配置文件) – 由 DispatcherServlet(org.springframework.web.servlet.DispatcherServlet)载入

参考链接

http://zhaoshijie.iteye.com/blog/1974682 – 只有解决办法,没有原因
Spring和SpringMVC父子容器关系初窥