【Spring容器】项目启动后初始化数据的两种实践方案

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

1.Servlet方式

 
  1. @Component

  2. public class InitDataServlet extends HttpServlet {

  3.  

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

  5.  

  6.    static AbstractApplicationContext ctx;

  7.  

  8.    static {

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

  10.    }

  11.  

  12.    /**

  13.     * serialVersionUID:

  14.     *

  15.     * @since JDK 1.6

  16.     */

  17.    private static final long serialVersionUID = 1L;

  18.  

  19.    /**

  20.     * 初始化数据

  21.     *

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

  23.     */

  24.    public void init() throws ServletException {

  25.  

  26.        loadBaseData();

  27.  

  28.    }

  29. }

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

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

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

2.InitializingBean方式

 
  1. @Component

  2. public class InitDataServlet implements InitializingBean {

  3.  

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

  5.  

  6.  @Override

  7.  public void afterPropertiesSet() throws Exception {

  8.  

  9.    loadBaseData();

  10.  

  11.  }

  12.  

  13. }

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.  

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

  5.  

  6.  @Override

  7.  public void onApplicationEvent(ContextRefreshedEvent event) {

  8.        //第一种方式

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

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

  11.        //}

  12.        //第二种

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

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

  15.        }

  16.  

  17.  }

  18.  

  19. }

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

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

0?wx_fmt=gif&wxfrom=5&wx_lazy=1

扩展阅读:

转载于:https://my.oschina.net/u/3669358/blog/1632109

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值