【Spring容器】项目启动后初始化数据的两种实践方案
2018-01-17 07:06
459 查看
早期业务紧急,没有过多的在意项目的运行效率,现在回过头看走查代码,发现后端项目(Spring MVC+MyBatis)在启动过程中多次解析mybatis的xml配置文件及初始化数据,对开发阶段开发人员反复启停项目造成很大的时间浪费,也即是下面的第一种方式。
这种方式应该是比较常见的,上述代码之所以这么写,是因为Servlet中无法使用使用Spring容器的上下文,只能在servlet中重新获取,这也就导致了两次容器的加载,与之相对应就是两次相关程序的调用。
以上代码,并结合web.xml中配置load-on-startup值为0,可以在项目启动后立即执行InitDataServlet方法。
后期优化成InitializingBean的方式重构,启动速度上更快一步。下面简单介绍下两种方式
application.xml配置文件
方法体内有一个if分支只是为了规避onApplicationEvent方法执行多次,在Spring MVC的项目中,系统会存在两个容器,一个是Root WebApplicationContext ,另一个就是我们自己的WebApplicationContext(作为Root WebApplicationContext的子容器),若不加以判断,会给系统造成不必要的负载或逻辑上的错误等等。
如果你还在使用第一种方式的话,建议重构为后两种方式。
扩展阅读:
一个5年码龄人的『2017个人总结与展望』
一个程序员的2017年书单整理
Elasticsearch实战总结
基于SpringCloud的Microservices架构实战案例-序篇
1.Servlet方式
@Component
public class InitDataServlet extends HttpServlet {
private static final Logger LOGGER = Logger.getLogger(InitDataServlet.class);
static AbstractApplicationContext ctx;
static {
ctx = new FileSystemXmlApplicationContext("classpath:conf/spring*.xml");
}
/**
* serialVersionUID:
*
*@since JDK 1.6
*/
private static final long serialVersionUID = 1L;
/**
*初始化数据
*
*@see javax.servlet.GenericServlet#init()
*/
public void init() throws ServletException {
loadBaseData();
}
}
这种方式应该是比较常见的,上述代码之所以这么写,是因为Servlet中无法使用使用Spring容器的上下文,只能在servlet中重新获取,这也就导致了两次容器的加载,与之相对应就是两次相关程序的调用。
以上代码,并结合web.xml中配置load-on-startup值为0,可以在项目启动后立即执行InitDataServlet方法。
后期优化成InitializingBean的方式重构,启动速度上更快一步。下面简单介绍下两种方式
2.InitializingBean方式
@Component
public class InitDataServlet implements InitializingBean {
private static final Logger LOGGER = Logger.getLogger(InitDataServlet.class);
@Override
public void afterPropertiesSet() throws Exception {
loadBaseData();
}
}
application.xml配置文件
<!-- 配置使其可扫描到InitDataServlet-->
<context:component-scan base-package="com.pkg.servlet"/>
<!-- 也可以在xml中配置bean,可以指定属性init-method。-->
3.ApplicationListener方式
@Component
public class InitDataServlet implements ApplicationListener<ContextRefreshedEvent> {
private static final Logger LOGGER = Logger.getLogger(InitDataServlet.class);
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
//第一种方式
//if (event.getApplicationContext().getDisplayName().equals("Root WebApplicationContext")) {
//TODO 编写自己的初始化数据方法
//}
//第二种
if(event.getApplicationContext().getParent() == null){
//TODO 编写自己初始化数据的方法
}
}
}
方法体内有一个if分支只是为了规避onApplicationEvent方法执行多次,在Spring MVC的项目中,系统会存在两个容器,一个是Root WebApplicationContext ,另一个就是我们自己的WebApplicationContext(作为Root WebApplicationContext的子容器),若不加以判断,会给系统造成不必要的负载或逻辑上的错误等等。
如果你还在使用第一种方式的话,建议重构为后两种方式。
扩展阅读:
一个5年码龄人的『2017个人总结与展望』
一个程序员的2017年书单整理
Elasticsearch实战总结
基于SpringCloud的Microservices架构实战案例-序篇
相关文章推荐
- 【Spring容器】项目启动后初始化数据的两种实践方案
- spring初始化完成后将基础数据放入项目缓存
- 【Spring实战】Spring容器初始化完成后执行初始化数据方法
- 最佳实践--Spring容器初始化完成之后执行某个方法
- spring容器启动,初始化某个方法(init)
- spring 在web容器启动时执行初始化方法
- Spring在Web容器启动时执行初始化方法
- spring 在web 容器启动时,执行FIFO队列初始化方法
- Spring项目启动时执行初始化方法
- spring在web容器启动时执行初始化方法
- <springBoot>(三)(入门篇)新建一个springBoot项目(两种启动的方式)
- Spring容器启动之后进行初始化操作
- 项目启动 spring初始化bean之后执行指定方法
- Tomcat启动时加载数据到缓存---web.xml中listener加载顺序(优先初始化Spring IOC容器)
- web.xml中配置Spring容器随项目启动
- Javaweb 项目启动数据初始化
- Tomcat启动时加载数据到缓存---web.xml中listener加载顺序(优先初始化Spring IOC容器)
- 第三周实践项目1(2)--顺序表的基本运算插入.删除数据,初始化.销毁线性表
- Spring启动容器初始化Listener
- spring心得2--bean的生命周期@Spring监听器的作用@Spring初始化容器案例分析@web项目使用