Java 类装入器通常通过在固定序列中的一个或多个位置查找类来工作。例如,从命令行运行应用程序时,装入应用程序的类装入器首先在文件(以及引导类路径上的其他文件)中查找,然后在类路径指定的目录和 JAR 文件中查找。rt.jar
Webapp类加载在原则上是相似的,但在实践中有点复杂。对于特定的 web 应用,Web 应用的类加载器按以下顺序查找类。例如,Tomcat 6 按以下顺序查找类:
- JVM 的引导类
- 系统类装入器类(此处描述))
- /WEB-INF/webapp 的类
- /WEB-INF/lib/*webapp 的.jar
- $CATALINA_首页/lib
- $CATALINA_首页/自由/*.jar
当然,一旦类装入器找到了它正在寻找的类,它就不再看了。因此,稍后在顺序中具有相同名称的类将不会加载。
复杂的是,Web 容器的每个 web 应用都有一个类加载器,这些类加载器委托给管理公共类的其他类加载器。在实践中,这意味着某些类对于整个容器(例如 1. 和 2.)只会加载一次,而其他类可能会被不同的类加载器加载多次。
(当一个类被多次装入时,它会导致不同的对象和不同的类静态。就 JVM 而言,该类的版本是不同的类型,您不能从一个版本类型转换到另一个版本。Class
最后,Tomcat可以配置为允许单个Web应用程序“热加载”。这需要停止 Web 应用,为其创建新的类装入器,然后重新启动它。
随访
所以。。。同步静态方法不会保护对已多次装入类的共享资源的访问?
这取决于细节,但可能不会。(或者看看如果换一种方式,如果一个类实际上已经被加载了多次,那么该类的每个“加载”的方法将访问一组不同的字段。static
static
如果确实希望单一实例应用程序类实例由同一容器中的多个 Web 应用共享,则最简单的方法是将类放入或等效项中。但你也应该问问自己,这是否是好的系统设计。考虑合并Web应用程序,或使用请求转发等而不是共享数据结构。单例模式在Web应用程序中往往很麻烦,这种风格更是如此。$CATALINA_HOME/lib