zoukankan      html  css  js  c++  java
  • 【Spring容器】项目启动后初始化数据的两种实践方案

    早期业务紧急,没有过多的在意项目的运行效率,现在回过头看走查代码,发现后端项目(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的子容器),若不加以判断,会给系统造成不必要的负载或逻辑上的错误等等。

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

    扩展阅读:

    成长的乐趣,在于分享!
    大龄程序员,一路走来,感慨颇多。闲暇时写写字,希望能给同行人一点帮助。
    本文版权归作者growithus和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    ural1018(树形dp)
    hdu1011(树形dp)
    poj1463(树形dp)
    poj1655(树形dp)
    poj1155(树形dp)
    hdu2196(树形dp)
    hdu1520(树形dp)
    hdu2126(求方案数的01背包)
    运用bootstrap框架的时候 引入文件的问题
    动态的改变标签内的src属性
  • 原文地址:https://www.cnblogs.com/growithus/p/11012213.html
Copyright © 2011-2022 走看看