在做WEB项目时,经常在项目第一次启动时利用WEB容器的监听、Servlet加载初始化等切入点为数据库准备数据,这些初始化数据 是系统开始运行前必须的数据,例如权限组、系统选项、默认管理员等等。但是项目若不是WEB工程,或者说还没用到WEB层(例如单元测试),这时应如何方 便地初始化数据呢?
借助Spring容器是个很好的解决方案。Spring框架提供了事件机制,而事件机制必须实现ApplicationListener监听器,因此我们 只要编写一个实现类实现该接口的onApplicationEvent方法,在方法体中检测数据库的初始化数据是否存在并选择初始化之。
第一步:定义一个类InitData实现ApplicationListener
import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Controller; import com.ebay.cloud.cms.typsafe.metadata.model.MetaClass; import com.ebay.tools.cms.exception.UtilityException; import com.ebay.tools.cms.util.CommonInterfaceUtility; import com.ebay.tools.cms.util.ExceptionUtils; import com.ebay.tools.cms.util.LoggerUtil; /** * @author Josh Wang(Sheng) * @email swang6@email.com * * This class used to initialize data / load data ON the application started */ @Controller public class InitData implements ApplicationListener<ApplicationEvent> { private Log logger = LogFactory.getLog(InitData.class); private static boolean isStart = false; private static Map<String, MetaClass> cmsMetas = new HashMap<String, MetaClass>(); public void onApplicationEvent(ApplicationEvent event) { if (!isStart) { isStart = true; LoggerUtil.info(logger, "Start to load CMS Meta data"); try { cmsMetas = CommonInterfaceUtility.getMetaClass(); } catch (UtilityException e) { LoggerUtil.error(logger, "Load Meta Class failed" + ExceptionUtils.getStackTraceMsg(e)); } LoggerUtil.info(logger,"End to load CMS Meta data"); LoggerUtil.info(logger,"Start to load Other data"); LoggerUtil.info(logger,"End to load Other data"); } }
第二步:解决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中。
@ContextConfiguration(locations = "file:../validator-web/src/main/webapp/WEB-INF/cms-validator-servlet.xml") public class BaseTest { /** * Set up the environment * @throws Exception */ @BeforeClass public static void setUp() throws Exception { } public static void print(String message) { System.out.println(message); } public static void printHighlight(String message) { System.err.println(message); } }
然后只需要在你的测试类上用这个Annotation:@RunWith(SpringJUnit4ClassRunner.class)
@RunWith(SpringJUnit4ClassRunner.class) public class TestCacheUtil extends BaseTest { @Test public void getCMSMetaAttributeType() throws UtilityException { } }
相关推荐
tomcat启动时立即调用quartz执行一次
这个属于与Spring整合的问题,Spring容器在初始化对象的时候会根据bean的scope配置来考虑是重新建立一个对象,还是继续使用原来的对象,拿struts2的action的bean来说,如果scope这个参数没有配置,默认就是单例,即...
原来是BlobByteArrayType数据类型本身具体数据访问的功能,它通过LobHandler将两次数据访问的动作隐藏起来,使Blob字段的操作在表现上和其他一般字段业类型无异,所以LobHandler即是那个"苦了我一个,幸福十亿人"的...
这个属于与Spring整合的问题,Spring容器在初始化对象的时候会根据bean的scope配置来考虑是重新建立一个对象,还是继续使用原来的对象,拿struts2的action的bean来说,如果scope这个参数没有配置,默认就是单例,即...
博客地址:... 1. 启动后访问http://localhost:8848/code,可见控制台输出codeMap中的值 2. 新建一个只有key和value两个字段的表code 3. 不要轻易浪费积分下载代码,没什么实质内容
.initialCacheNames(cacheNames) /* 注意这两句的调用顺序,一定要先调用该方法设置初始化的缓存名,再初始化相关的配置 */ .withInitialCacheConfigurations(configMap).build(); return cacheManager; } 框架中...
6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用...
Activity Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务,是一个负责与用户交互的组件 SSH 为 Struts+Spring+Hibernate的一个集成框架,是目前较流行的一种Web应用程序开源框架。...
6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个EJB对象的count()方法,保证Bean正常被激活和钝化,EJB对象是用...
spring Location* 任何以location开头的参数,每个参数都是指定一个spring的配置文件,在参数没有设置的情况下DWR会去读取spring的全局的配置文件. spring beanName 从配置文件中读取的bean的名称 “scope参数允许你...
4. TaskService: 在Activiti中业务流程定义中的每一个执行节点被称为一个Task,对流程中的数据存取,状态变更等操作均需要在Task中完成。TaskService提供了对用户Task 和Form相关的操作。它提供了运行时任务查询、...
一、CacheCloud是做什么的CacheCloud提供一个Redis云管理平台:实现多种类型(Redis Standalone、Redis Sentinel、Redis Cluster)自动部署、解决Redis实例碎片化现象、提供完善统计、监控、运维功能、减少开发人员的...
例如:我们要取得session中储存一个属性username的值,可以利用下列方法: session.getAttribute("username") 取得username的值, 在EL中则使用下列方法 ${sessionScope.username} 2)与输入有关的隐含对象 与...
1.4 第一个Java程序 8 1.4.1 开发源代码 8 1.4.2 编译运行 9 1.5 小结 11 第2章 基本数据类型——构建Java 大厦的基础 12 2.1 源代码注释 12 2.1.1 单行注释 12 2.1.2 区域注释 12 2.1.3 文档...
【资源说明】 ...1. 一个大坑就是rocketmq,我是现学现用的,曾因为理论不完善而导致代码多次出现大改, 1.1. 主要坑有两个,一个两阶段提交如何确保事务最终一致性(其实就是这学期nosql的理论实践)
1.在myeclipse中新建一个项目jeecms,将服务器中jeecms项目下web-inf文件夹下内容拷到新建项目中 解压缩jeecms-3.0.2-final-src,在src文件夹下会看到有三个压缩文件,如果只想进行普通的二次开发,可以只导入cms这...
上面的语法格式中,sequence就是一个集合对象,也可以是一个表达式,但该表达式将返回一个集合对象,而item是一个任意的名字,就是被迭代输出的集合元素.此外,迭代集合对象时,还包含两个特殊的循环变量: item_index:...
如果你使用的是 Idea 或 eclipse 开发,请直接运行 **OAuthServerApplication** 这个方法即可启动服务。 **访问地址** ``` http://localhost:8043/uaa/swagger-ui.html ``` ![uaa]...
2.2.3. 本地方法区(线程私有) ................................................................................................................ 23 2.2.4. 堆(Heap-线程共享)-运行时数据区 .....................