Spring初始化完成后直接执行一个方法,初始化数据(解决方法并执行两次)

在做WEB项目时,经常在项目第一次启动时利用WEB容器的监听、Servlet加载初始化等切入点为数据库准备数据,这些初始化数据 是系统开始运行前必须的数据,例如权限组、系统选项、默认管理员等等。但是项目若不是WEB工程,或者说还没用到WEB层(例如单元测试),这时应如何方 便地初始化数据呢?

借助Spring容器是个很好的解决方案。Spring框架提供了事件机制,而事件机制必须实现ApplicationListener监听器,因此我们 只要编写一个实现类实现该接口的onApplicationEvent方法,在方法体中检测数据库的初始化数据是否存在并选择初始化之。

第一步:定义一个类InitData实现ApplicationListener

  1. import java.util.HashMap;
  2. import java.util.Map;
  3.  
  4. import org.apache.commons.logging.Log;
  5. import org.apache.commons.logging.LogFactory;
  6. import org.springframework.context.ApplicationEvent;
  7. import org.springframework.context.ApplicationListener;
  8. import org.springframework.stereotype.Controller;
  9.  
  10. import com.ebay.cloud.cms.typsafe.metadata.model.MetaClass;
  11. import com.ebay.tools.cms.exception.UtilityException;
  12. import com.ebay.tools.cms.util.CommonInterfaceUtility;
  13. import com.ebay.tools.cms.util.ExceptionUtils;
  14. import com.ebay.tools.cms.util.LoggerUtil;
  15.  
  16. /**
  17. * @author Josh Wang(Sheng)
  18. * @email swang6@email.com
  19. *
  20. * This class used to initialize data / load data ON the application started
  21. */
  22. @Controller
  23. public class InitData implements ApplicationListener<ApplicationEvent> {
  24.  
  25. private Log logger = LogFactory.getLog(InitData.class);
  26.  
  27. private static boolean isStart = false;
  28.  
  29. private static Map<String, MetaClass> cmsMetas = new HashMap<String, MetaClass>();
  30.  
  31. public void onApplicationEvent(ApplicationEvent event) {
  32. if (!isStart) {
  33. isStart = true;
  34. LoggerUtil.info(logger, "Start to load CMS Meta data");
  35.  
  36. try {
  37. cmsMetas = CommonInterfaceUtility.getMetaClass();
  38. } catch (UtilityException e) {
  39. LoggerUtil.error(logger, "Load Meta Class failed" + ExceptionUtils.getStackTraceMsg(e));
  40. }
  41.  
  42. LoggerUtil.info(logger,"End to load CMS Meta data");
  43.  
  44. LoggerUtil.info(logger,"Start to load Other data");
  45.  
  46. LoggerUtil.info(logger,"End to load Other data");
  47. }
  48.  
  49. }

 第二步:解决onApplicationEvent(方法被执行两次以上的问题:

原因:

在web 项目中(spring mvc),系统会存在两个容器,一个是root application context ,另一个就是我们自己的 projectName-servlet  context(作为root application context的子容器)。 这种情况下,就会造成onApplicationEvent方法被执行两次。

解决方法:

如代码所示,只需要使用一个类变量isStart即可。

需要注意的是,一定要加Annotation @Controller,这样才表示是一个Spring的Bean(否则在相关Spring的xml中配置),才能被Spring容器处理。

第三步,写一个Spring JunitTest,注意相关的Annotation

需要注意的就是在类上面加入如下两个Annotation即可:

@ContextConfiguration(locations = "file:../validator-web/src/main/webapp/WEB-INF/cms-validator-servlet.xml")

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration用于加载spring的核心配置文件,因为这个操作是一个公共的操作,所以我们常常可以写在一个BaseTest中。

  1. @ContextConfiguration(locations = "file:../validator-web/src/main/webapp/WEB-INF/cms-validator-servlet.xml")
  2. public class BaseTest {
  3.  
  4. /**
  5. * Set up the environment
  6. * @throws Exception
  7. */
  8. @BeforeClass
  9. public static void setUp() throws Exception {
  10.  
  11. }
  12.  
  13. public static void print(String message) {
  14. System.out.println(message);
  15. }
  16.  
  17. public static void printHighlight(String message) {
  18. System.err.println(message);
  19. }
  20.  
  21. }

然后只需要在你的测试类上用这个Annotation:@RunWith(SpringJUnit4ClassRunner.class)

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. public class TestCacheUtil extends BaseTest {
  3.  
  4. @Test
  5. public void getCMSMetaAttributeType() throws UtilityException {
  6.  
  7. }
  8. }

spring 初始化之后执行的方法的更多相关文章

  1. Spring Bean初始化之后执行指定方法

    转: Spring Bean初始化之后执行指定方法 2017年07月31日 15:59:33 vircens 阅读数:24807   Spring Bean初始化之后执行指定方法 在运用Spring进 ...

  2. ApplicationListener接口,在spring容器初始化后执行的方法

    一.如果我们希望在Spring容器将所有的Bean都初始化完成之后,做一些操作,那么就可以使用ApplicationListener接口,实现ApplicationListener接口中的onAppl ...

  3. Orchard源码分析(5.1):Host初始化(DefaultOrchardHost.Initialize方法)

    概述 Orchard作为一个可扩展的CMS系统,是由一系列的模块(Modules)或主题(Themes)组成,这些模块或主题统称为扩展(Extensions).在初始化或运行时需要对扩展进行安装:De ...

  4. spring容器初始化执行某个方法

    在做web项目开发中,尤其是企业级应用开发的时候,往往会在工程启动的时候做许多的前置检查. 比如检查是否使用了我们组禁止使用的Mysql的group_concat函数,如果使用了项目就不能启动,并指出 ...

  5. 当spring 容器初始化完成后执行某个方法

    在做web项目开发中,尤其是企业级应用开发的时候,往往会在工程启动的时候做许多的前置检查. 比如检查是否使用了我们组禁止使用的Mysql的group_concat函数,如果使用了项目就不能启动,并指出 ...

  6. 当spring 容器初始化完成后执行某个方法 防止onApplicationEvent方法被执行两次

    在做web项目开发中,尤其是企业级应用开发的时候,往往会在工程启动的时候做许多的前置检查. 比如检查是否使用了我们组禁止使用的Mysql的group_concat函数,如果使用了项目就不能启动,并指出 ...

  7. spring初始化bean时执行某些方法完成特定的初始化操作

    在项目中经常会在容器启动时,完成特定的初始化操作,如资源文件的加载等. 一 实现的方式有三种: 1.使用@PostConstruct注解,该注解作用于void方法上 2.在配置文件中配置init-me ...

  8. Spring中初始化bean和销毁bean的时候执行某个方法的详解

    关于在spring  容器初始化 bean 和销毁前所做的操作定义方式有三种: 第一种:通过注解@PostConstruct  和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作 ...

  9. spring 容器加载完成后执行某个方法

    理论 刚好再开发过程中遇到了要在项目启动后自动开启某个服务,由于使用了spring,我在使用了spring的listener,它有onApplicationEvent()方法,在Spring容器将所有 ...

随机推荐

  1. <实训|第九天>掌握linux中普通的权限控制和三种特殊的权限(sst),做合格的运维工程师

    linux中,权限的学习是必不可少的,不论是作为一名运维工程师或者是单一的管理者,学习好linux中的权限控制,你就可以保护好自己的隐私同时规划好你所管理的一切. 权限的学习是很多的,不要认为自己已经 ...

  2. 告别编译运行 ---- Android Studio 2.0 Preview发布Instant Run功能

    以往的Android开发有一个头疼的且拖慢速度的问题,就是你每改一行代码要想看到结果必须要编译运行到手机或者模拟器上,而且需要从头(可能是登录界面)一直点击到你修改的界面为止.开发一个完整的Andro ...

  3. 两道关于JS的小考题(闭包与中间件)

    题目一:写一个javascript函数 calculate,该函数有如下性质 calculate() = 0; calculate(2)() = 2; calculate(3)(4)(1)(5)() ...

  4. 有趣的问题--12 coins problem

    问题描述: 12个金币,其中有一枚是假的,重量与众不同. 现有一架天平,需要你用最少的次数来称重,然后告诉我: (1)哪个金币是假的 (2)它到底是更轻还是更重.   (注:此处为3次)     {解 ...

  5. jQuery插件---exselect实现联动

    <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title> ...

  6. Beta版本冲刺Day4

    会议讨论: 628:由于昨天的考试我们组目前只把项目放到了服务器上,配置Java环境遇到了问题.601:将一些原来的界面进行了修改,修改成了更加美观的外形. 528:进行一些还未完成得到功能,比如查询 ...

  7. window配置nginx+php+mysql

    博客来源: http://www.cnblogs.com/wuzhenbo/p/3493518.html 启用nginx   D:\nginx>nginx.exe 重启 D:\nginx> ...

  8. Openstack Basic Networking 翻译

    自己翻译,加强理解.并学习英文和写作. 英文地址:http://docs.openstack.org/networking-guide/intro_basic_networking.html 目录: ...

  9. Elasticsearch 权威指南

    Elasticsearch 权威指南 http://fuxiaopang.gitbooks.io/learnelasticsearch/content/index.html

  10. [转]Java_List元素的遍历和删除

    原文地址:http://blog.csdn.net/insistgogo/article/details/19619645 1.创建一个ArrayList List<Integer> li ...