早期业务紧急,没有过多的在意项目的运行效率,现在回过头看走查代码,发现后端项目(Spring MVC+MyBatis)在启动过程中多次解析mybatis的xml配置文件及初始化数据,对开发阶段开发人员反复启停项目造成很大的时间浪费,也即是下面的第一种方式。

1.Servlet方式


  1. @Component

  2. public class InitDataServlet extends HttpServlet {

  3.    private static final Logger LOGGER = Logger.getLogger(InitDataServlet.class);

  4.    static AbstractApplicationContext ctx;

  5.    static {

  6.        ctx = new FileSystemXmlApplicationContext("classpath:conf/spring*.xml");

  7.    }

  8.    /**

  9.     * serialVersionUID:

  10.     *

  11.     * @since JDK 1.6

  12.     */

  13.    private static final long serialVersionUID = 1L;

  14.    /**

  15.     * 初始化数据

  16.     *

  17.     * @see javax.servlet.GenericServlet#init()

  18.     */

  19.    public void init() throws ServletException {

  20.        loadBaseData();

  21.    }

  22. }

这种方式应该是比较常见的,上述代码之所以这么写,是因为Servlet中无法使用使用Spring容器的上下文,只能在servlet中重新获取,这也就导致了两次容器的加载,与之相对应就是两次相关程序的调用。

以上代码,并结合web.xml中配置load-on-startup值为0,可以在项目启动后立即执行InitDataServlet方法。

后期优化成InitializingBean的方式重构,启动速度上更快一步。下面简单介绍下两种方式

2.InitializingBean方式


  1. @Component

  2. public class InitDataServlet implements InitializingBean {

  3.  private static final Logger LOGGER = Logger.getLogger(InitDataServlet.class);

  4.  @Override

  5.  public void afterPropertiesSet() throws Exception {

  6.    loadBaseData();

  7.  }

  8. }

application.xml配置文件


  1. <!-- 配置使其可扫描到InitDataServlet-->

  2. <context:component-scan base-package="com.pkg.servlet"/>

  3. <!-- 也可以在xml中配置bean,可以指定属性init-method。-->

3.ApplicationListener方式


  1. @Component

  2. public class InitDataServlet implements ApplicationListener<ContextRefreshedEvent> {

  3.  private static final Logger LOGGER = Logger.getLogger(InitDataServlet.class);

  4.  @Override

  5.  public void onApplicationEvent(ContextRefreshedEvent event) {

  6.        //第一种方式

  7.        //if (event.getApplicationContext().getDisplayName().equals("Root WebApplicationContext")) {

  8.            //TODO 编写自己的初始化数据方法

  9.        //}

  10.        //第二种

  11.        if(event.getApplicationContext().getParent() == null){

  12.            //TODO 编写自己初始化数据的方法

  13.        }

  14.  }

  15. }

方法体内有一个if分支只是为了规避onApplicationEvent方法执行多次,在Spring MVC的项目中,系统会存在两个容器,一个是Root WebApplicationContext ,另一个就是我们自己的WebApplicationContext(作为Root WebApplicationContext的子容器),若不加以判断,会给系统造成不必要的负载或逻辑上的错误等等。

如果你还在使用第一种方式的话,建议重构为后两种方式。

扩展阅读:

【Spring容器】项目启动后初始化数据的两种实践方案的更多相关文章

  1. spring boot项目获取application配置文件参数的两种方式

    前言:了解过spring boot这个技术的,应该知道spring boot的核心配置文件application.properties,当然也可以通过注解自定义配置文件**.properties的信息 ...

  2. springboot 学习之路 9 (项目启动后就执行特定方法)

    目录:[持续更新.....] spring 部分常用注解 spring boot 学习之路1(简单入门) spring boot 学习之路2(注解介绍) spring boot 学习之路3( 集成my ...

  3. spring boot 项目启动无任何反应

    遇到的问题 spring boot项目启动后无任何报错,ps有进程,nohub无日志 定位 更换jar包,问题依然存在,将jar包放到其他服务器,运行正常,排除打包问题 同服务器其他系统运行正常,但停 ...

  4. Tomcat启动时加载数据到缓存---web.xml中listener加载顺序(例如顺序:1、初始化spring容器,2、初始化线程池,3、加载业务代码,将数据库中数据加载到内存中)

    最近公司要做功能迁移,原来的后台使用的Netty,现在要迁移到在uap上,也就是说所有后台的代码不能通过netty写的加载顺序加载了. 问题就来了,怎样让迁移到tomcat的代码按照原来的加载顺序进行 ...

  5. Spring Boot 2 (七):Spring Boot 如何解决项目启动时初始化资源

    Spring Boot 2 (七):Spring Boot 如何解决项目启动时初始化资源 在项目启动的时候需要做一些初始化的操作,比如初始化线程池,提前加载好加密证书等.今天就给大家介绍一个 Spri ...

  6. SpringBoot 源码解析 (三)----- Spring Boot 精髓:启动时初始化数据

    在我们用 springboot 搭建项目的时候,有时候会碰到在项目启动时初始化一些操作的需求 ,针对这种需求 spring boot为我们提供了以下几种方案供我们选择: ApplicationRunn ...

  7. 让Spring Boot项目启动时可以根据自定义配置决定初始化哪些Bean

    让Spring Boot项目启动时可以根据自定义配置决定初始化哪些Bean 问题描述 实现思路 思路一 [不符合要求] 思路二[满足要求] 思路三[未试验] 问题描述 目前我工作环境下,后端主要的框架 ...

  8. spring项目启动后,获取bean的方法总结

    如果在web项目中,用到定时器的朋友可能会遇到使用spring注解的方式获取bean的时候报空指针的异常.这是就可以使用手工的方法获取spring容器中的bean了. 下面是具体的方法: 1.先说一个 ...

  9. web容器启动后自动执行程序的几种方式比较

    1.       背景 1.1.       背景介绍 在web项目中我们有时会遇到这种需求,在web项目启动后需要开启线程去完成一些重要的工作,例如:往数据库中初始化一些数据,开启线程,初始化消息队 ...

随机推荐

  1. php 获取今日、昨日、本周,上周、本月,上月,季度的起始时间戳和结束时间戳的方法

    php 获取今日.昨日.上周.本月的起始时间戳和结束时间戳的方法,主要使用到了 php 的时间函数 mktime.下面首先还是直奔主题以示例说明如何使用 mktime 获取今日.昨日.上周.本月的起始 ...

  2. 【Gerrit】自动设置reviewer

    gerrit 提供了一种代码review解决方案,但每次代码提交之后都要设置每个commit的code reviewer, 实在是痛苦. gerrit 在官方说明文档里面提供了解决方法,地址:http ...

  3. Win10《芒果TV》商店版更新v3.2.2:新增对Win10产品专用会员兑换码支持,全新的最具价值用户纪念奖励

    在WinHEC2016宣布Win10和ARM历史性结合之际,<芒果TV>UWP版迅速更新v3.2.2版,主要是新增对Win10产品专用会员兑换码支持,推出全新的最具价值用户纪念奖励(具有唯 ...

  4. 在DELPHI中*.wav 文件怎么加到资源文件中

    比较“流行”的说法是:“16位的Delphi   1.0和32位的Delphi2.0.3.0都提供了资源         编译工具,其中   Delphi   1.0的资源编译器叫BRCC.EXE,D ...

  5. SQL Server Update 所有表的某一列(列名相同,类型相同)数值

    ); WITH T AS (SELECT SchemaName = c.TABLE_SCHEMA, TableName = c.TABLE_NAME, ColumnName = c.COLUMN_NA ...

  6. Database time zone version is 18. It is older than current release time zone version 26

    [oracle@raca1 12.2.0]$ sqlplus / as sysdba SQL Production :: Copyright (c) , , Oracle. All rights re ...

  7. LINUX基础内容

    在Linux中,有三种基本的文件类型: 1) 普通文件 普通文件是以字节为单位的数据流,包括文本文件.源码文件.可执行文件等.文本和二进制对Linux来说并无区别,对普通文件的解释由处理该文件的应用程 ...

  8. 我写的一个Qt 显示二维码( QR Code)的控件(可以去掉对 libpthread 的依赖,而且编译出的库文件可以在 vc2010 的release 模式下使用)

    最近一个项目需要显示二维码,所以花了点时间(只用了一个晚上,写的很不完善),写了个显示二维码的控件.当然这个控件用到了些开源的代码,比如qrencode,所以我也打算把我的代码开源. 我的代码参考了 ...

  9. MacOS X编译OpenSceneGraph

    本文主要记录在MacOS X上编译OpenSceneGraph,方便日后查阅.所使用的环境如下: MacOS X 10.10 Yosemite XCode 6.3.2 CMake 3.3.0 Open ...

  10. 为什么说 2017 年你必须要学习 Go 了(多核,网络,多人协作,简单非OO,没有注解,Native,垃圾收集,代码优雅),附两个评论

    为什么要学习Go Go是未来的服务端语言— Tobias Lütke, Shopify.在过去的几年中,Golang逐步流行起来. 还有什么能比一门新语言让码农们疯狂呢? 因此,我开始学习了一段时间G ...