`
Everyday都不同
  • 浏览: 713450 次
  • 性别: Icon_minigender_1
  • 来自: 宇宙
社区版块
存档分类
最新评论

ServeltContext的理解和一种使用场景

阅读更多

最近做项目,用到了一个比较不熟悉的东西,但我自己又觉得很有用。所以记录下吧……

 

1.ServletContext  的使用

ServletContext对象是在Web应用程序装载时初始化的,它的生命周期是随着服务器启动而开始,服务器关闭而结束。即只要你的web应用程序处于启动状态,它就是一直存活的。而当你关闭web应用程序时,它也会被回收。

ServletContext对象之setAttribute和getAttribute的经典用法:

ServletContext和HttpServletRequest, HttpSession一样,可以作为1个map结构而使用。区别在于他们之间的作用范围和生命周期不同。

当你希望程序在某个类中,只执行1次,而接下来就不再执行。在web环境中,可能多次调用的类往往是action或者定时任务调度类。当我们希望action或定时任务调度类无论被调用多少次,某段代码只执行1次时,可以用ServletContext来标记。如有一个定时任务调度类TestTrigger(定时任务的配置略):

 

SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
		WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
		ServletContext servletContext =  webApplicationContext.getServletContext();
		String count = (String) servletContext.getAttribute("count");
		if (StringUtils.equals("1", count)){ // 测试用
			System.out.println(sdf.format(new Date()) + ": TestTrigger非第1次执行。。");
		}else{
			servletContext.setAttribute("count", "1");
			System.out.println(sdf.format(new Date()) + ": TestTrigger第一次执行。。。");
		}
 又有一个Action:

 

 

@RequestMapping("/test/context.json")
	@ResponseBody
	public void test() {
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
		WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
		ServletContext servletContext =  webApplicationContext.getServletContext();
		String count = (String) servletContext.getAttribute("count");
		if (StringUtils.equals("1",count)){ // 测试用
			System.out.println(sdf.format(new Date()) + ": TestAction非第1次执行。。");
		}else{
			servletContext.setAttribute("count", "1");
			System.out.println(sdf.format(new Date()) + ": TestAction第一次执行。。。");
		}
	}
 启动web项目会发现,如果【先】在浏览器输入地址:http://localhost:8080/项目名/test/context.json 而定时任务调度类TestTrigger【后】被触发,会发现在控制台输出以下结果:
 
14:22:27: TestAction第一次执行。。。
14:23:00: TestTrigger非第1次执行。
以上输出结果表明:ServletContext的作用范围是整个web项目的,等你再次调用TestAction时,并且定时任务再次被调度时。打印结果是:
14:24:00: TestTrigger非第1次执行。
14:24:30: TestAction非第1次执行。
这说明,我们通过测试,可以达到某段代码在整个web项目只执行一次的效果。同样地,通过控制,先调度定时任务类,后访问该Action。初次的打印结果将会是相反的。
当然,以上只是测试ServletContext的作用范围的测试。在实际开发中,肯定是每个Action或定时任务调度类都会有自己的setAttribute的操作。因为每个Action或定时任务调度类都可能有【各自】的“只执行一次”的代码逻辑。
比如在上述测试中,TestTrigger可以setAttribute("testTriigger", "1") TestAction则可以setAttribute("testAction", "1") 。这样可以做到控制他们无论被调度或访问多少次,某些只需执行1次的代码片段可以不用每次都去执行,造成性能上的瓶颈。
Action或定时任务调度类的(1)static静态代码块的代码(2)static final属性的定义  会在web容器初始化的时候就执行且执行一次,但现实中并不推荐这么做。
另外需要注意的是:
1)只要在一个web工程里,无论你通过ContextLoader.getCurrentWebApplicationContext();方法创建多少次WebApplicationContext,你得到的始终是同一个WebApplicationContext对象;且无论你通过 webApplicationContext.getServletContext();创建多少次ServletContext,得到的也始终是同一个ServletContext对象。——这与ServletContext的生命周期和作用范围有关;
2)你setAttribute("test","first")再setAttribute("test","second")。再getAttribute("test")得到的会是second,因为会被第二次setAttribute操作覆盖。
小结:
1)ServletContext的生命周期和作用范围。
2)当你需要控制某段代码在无论该类被访问或调度N次,都只需执行1次该段代码的时候;需要在不同的调度类中共同使用一个变量的时候  不妨试试用ServletContext;
1
2
分享到:
评论
1 楼 念念不忘丶又怎樣 2015-09-17  
    

相关推荐

Global site tag (gtag.js) - Google Analytics