Singleton 模式通过私有化构造方法和 static 成员变量,提供全局范围内的唯一实例。然而,在 WEB 应用程序中,存在一个陷阱!

1、编写 Singleton 类

先来看一个单例: TestStaticInWeb.java

Code:

[Ctrl+A Select All]

这个单例很简单,通过 getInstance() 获得唯一实例,通过 getCreateTime() 来获得该唯一实例的创建时间。

普通情况下,这是没问题的,然而,在 Web 应用程序中,它的表现又如何呢?

2、构建 Web 应用程序

(1)编写一个 JSP,在这个 JSP 中显示出上述单例的相关信息:index.jsp

Code:

[Ctrl+A Select All]

(2)创建一个目录,名称为 testA,在 testA 下建 WEB-INF

(3)在 WEB-INF 下建 lib 目录

(4)在 WEB-INF 目录下建立 web.xml

Code:

[Ctrl+A Select All]

(5)把 index.jsp 放到 testA 目录下

(6)把 TestStaticInWeb.java 编译并打包成 test.jar,并拷贝到 testA\WEB-INF\lib 目录下

(7)把 testA 目录整个复制一份,然后重命名为 testB

(8)把 testA 和 testB 一起拷贝到 tomcat\webapps 目录下去

(9)启动 Tomcat
  
3、查看运行结果

(1)打开 IE,输入 [url]http://localhost:8080/testA[/url],得下如下结果: 
testA-1

(2)输入 [url]http://localhost:8080/testB[/url],得到如下结果:
testB-1

显然,上述两个结果是不一样的!在 Tomcat,显然存在两个 TestStaticInWeb 类的实例,也就是说,通过单例模式,得到的唯一实例并不“唯一”!

4、原因何在

在一个 ClassLoader 的作用范围内,一个类只会被 load 一次,对于用 static 修改的类或变量,也只会存在一份。

通常情况下,一个 JVM 对应着一个 ClassLoader,但在 Tomcat 等 J2EE 容器内,ClassLoader 则是相对复杂的,一个 JVM 可能对应着多个 ClassLoader,而且 ClassLoader 之间,是层次的结构。根据 Web 应用程序的相关规范(参见 Java Servlet SpecificationVersion 2.4 第 9 章:Web Applications),部署在 Tomcat 中的每个 webapp 都有一个与之对应的特殊的 ClassLoader,这个 ClassLoader 是在系统的 System ClassLoader 的基础上,优先 load 位于 WEB-INF/classes 和 WEB-INF/lib/*.jar 中的 class 文件。

由于 testA 和 testB 分属于两个不同的 webapp,所以,它们所得到的 TestStaticInWeb 类的 ClassLoader 也不一样。此时,单例模式只能保证在同一个 webapp 内部唯一,不能保证一个 JVM(即 Tomcat 容器)范围内唯一。

5、解决办法

如果确实要在 Tomcat 范围内唯一,则可以把 test.jar 拷贝到 Tomcat\common\lib 目录下去,并从 WEB-INF\lib 目录下删除之(重要!否则会出错!)。

以下是拷贝到 Tomcat\common\lib 目录下去之后的结果:

可以看出,这种方案下,TestStaticInWeb 类都是由系统的 ClassLoader 读取和初始化的,能保证全局唯一。
testA-2

testB-2

6、下载

单击这里可以下载 WEB 应用程序,源码位于 WEB-INF/src 目录下。

本文中的例子,在 Tomcat 5.5.15 + JDK 1.4 环境下通过。

附件:http://down.51cto.com/data/2347369

本文转自 豪客 51CTO博客,原文链接:http://blog.51cto.com/wakan/7216,如需转载请自行联系原作者

陷阱:在 WebApp 中谨防 Singleton 错误相关推荐

  1. singleton 类_在Java中对Singleton类进行双重检查锁定

    singleton 类 Singleton类在Java开发人员中非常常见,但是它给初级开发人员带来了许多挑战. 他们面临的主要挑战之一是如何使Singleton保持为Singleton? 也就是说,无 ...

  2. 在Java中对Singleton类进行双重检查锁定

    Singleton类在Java开发人员中非常常见,但是它给初级开发人员带来了许多挑战. 他们面临的主要挑战之一是如何使Singleton保持为Singleton? 也就是说,无论出于何种原因,如何防止 ...

  3. HOW-TO:带有Spring MVC的Tomcat中的自定义错误页面

    默认的Tomcat错误页面看起来很可怕. 此外,它们可能会公开有价值的信息,包括服务器版本和异常堆栈跟踪. Servlet规范提供了一种通过web.xml配置异常行为的方法. 可以配置对特定Java异 ...

  4. C++ 中的Singleton 类的实现

    摘要:ANSI C++ 中的 Singleton 实现说难不难,说容易也不容易,很多人写 ANSI C++ 的 Singleton class 都有错误.这篇文章讨论怎样在 ANSI c++ 中写 S ...

  5. 在Wicket中配置404错误页面

    始终建议为" 404页面未找到"错误自定义一个不错的错误页面. 本指南向您展示如何在Wicket中配置404错误页面. 1.错误页面 为Wicket创建错误页面和类. packag ...

  6. JAVA Web项目中所出现错误及解决方式合集(不断更新中)

    JAVA Web项目中所出现错误及解决方式合集 前言 一.几个或许会用到的软件下载官网 二.Eclipse的[preferences]下没有[sever]选项 三.Tomcat的安装路径找不到 四.T ...

  7. Sql Server 因为触发器问题导致数据库更新报错“在触发器执行过程中引发了错误,批处理已中止”的问题处理...

    在维护一个非常旧的项目时,由于该项目版本已经非常老了,而且在客户现场运行的非常稳定,更要命的是本人目前没有找到该项目的代码,为了处理一个新的需求而且还不能修改程序代码,于是决定从数据库入手,毕竟该项目 ...

  8. react 错误边界_React with GraphQL和错误边界中的自定义错误页面

    react 错误边界 by Abi Noda 通过Abi Noda React with GraphQL和错误边界中的自定义错误页面 (Custom error pages in React with ...

  9. 诊断IIS中的ASP0115错误

    诊断IIS中的ASP0115错误 作者:未知 重要说明:本文包含有关修改注册表的信息.修改注册表之前,一定要备份注册表,并且一定要知道在发生问题时如何还原注册表.有关如何备份.还原和编辑注册表的信息, ...

最新文章

  1. KVM — 与 QEMU 和 Libvirt 的关系
  2. 导入训练好的决策树文件_决策树在sklearn中的实现
  3. 阿里研究员谷朴:警惕软件复杂度困局
  4. 升讯威微信营销系统开发教程:(1)订阅号和服务号深入分析
  5. php删除菜单栏,如何删除WordPress站点健康状态面板和菜单项
  6. 计算机职称业务工作业绩总结,档案职称工作业绩
  7. http://java.sun.com/jsp/jstl/core cannot be resolved(含有jstl1.2jar包网盘)
  8. VC++ Tab Control控件的使用
  9. 强悍的 Ubuntu —— 强悍的任意进制转换命令行工具 bc
  10. python难学吗-Python为什么那么受欢迎?学习Python难不难?
  11. JavaWeb 基础系列篇
  12. windows控制台cmd乱码的解决办法
  13. ROC曲线的绘制过程/AUC/TPR、FPR、敏感度和特异度
  14. 看完你就明白的锁系列之自旋锁
  15. Casbin-authz-plugin:基于Casbin的Docker权限管理、访问控制插件
  16. 关闭eclipse控制台console中的非Java Server(ESLint、Angular Language Server等)
  17. 一亩三分地每日答题答案
  18. vue 防抖节流,开箱即用
  19. 红米3s运行linux,小米红米3S 3X(Redmi 3S)刷机教程,看教程刷机
  20. 建一个java项目并部署到weblogic服务器

热门文章

  1. mongodb mysql配置_mongoDB数据库原生配置
  2. form表单提交按钮点击事件先触发还是提交数据先触发_如何实现图片上传并保存到数据库?...
  3. 我,27岁,程序员,今年无情被辞:该转行还是降薪和年轻人抢饭碗?
  4. centos 文件夹网络连接_CentOS的网络配置的命令详解
  5. expec不管异常 try_java – 如何使用ExpectedException规则在一个测试中测试多个异常?...
  6. 模型ks_风控建模 模型指标篇
  7. 死磕java_死磕 java同步系列之AQS起篇
  8. Farthest Point Sampling on 2d image
  9. Boost Graph Library 快速入门
  10. 20复变函数的积分(六)