Tomcat Classloader 如何在同一个 JVM 中分离不同的 Webapps 对象范围?
由于 Tomcat 可以同时加载多个 webapp,并且这些 webapp 可以单独工作,互不干扰,并且工作在同一个 JVM 中.所以我很困惑tomcat如何处理同一个JVM中的对象范围.
Since Tomcat can load more than one webapp at once, and those webapps can work separately, and do not disturb each other, and they work in same JVM. So I am very confused about how tomcat handle The Object scope in the same JVM.
例如,我在两个不同的 Web 应用程序中都有一个单例对象,而 tomcat 将为每个生成两个不同的单例对象.我一直认为单例对象在同一个JVM中只有一个对象,但在tomcat JVM中可能有两个或更多.
For example I have a singleton object in both of the two different Webapps, and tomcat will generate two different singleton Object for each. I always thought that the singleton object have only one object in the same JVM, but in tomcat JVM there maybe has two or more.
我已经阅读了一些关于 ClassLoader 的信息,Tomcat 有自己的 WebAppClassLoader 来加载 webapps.那么这是否意味着这里的对象范围是 ClassLoader 还是我错了.有谁知道这个或者可以给我一些关于tomcat工作内存布局的信息?
I have read some info about the ClassLoader, Tomcat has its own WebAppClassLoader to load webapps. So does it mean the Object Scope here is the ClassLoader or am I wrong. Does anyone know about this or can give me some info about tomcat work memory layout?
推荐答案
所有的秘密都在那些 ClassLoader
实例的背后.
All the secrets is behind those ClassLoader
instances.
类的状态(如所有静态变量、字节码等)由加载该类的类加载器确定范围(一个类在 JVM 中通过其完全限定的名称和加载该类的类加载器来标识.这不完全是一个范围,但将其视为范围通常有助于更好地理解这一点).
The state of the class (like all static variables, byte code and so on) is scoped by the class loader which loads that class (a class is identified in JVM by its fully qualiflied name and the class loader loading the class. This is not exactly a scope, but thinking as scope usually helps understanding this better).
所以如果一个类被两个不同的类加载器加载,这个类在虚拟机中存在两次,它有两组静态字段,可以有不同的字节码(比如不同的方法实现)等等.请注意,即使它们的名称相同,这两个对象也不能相互转换.普通"Java 应用程序的所有类都由类加载器层次结构加载,并且每个类只加载一次.
So if a class is loaded by two different class loaders, this class exists twice within the VM, it has two sets of static fields, can have different byte code (like different method implementations) and all such. Note that these two objects cannot be cast to each other even their names are identical. "Normal" Java applications have all classes loaded by a class loader hierarchy and every class is only loaded once.
对于更复杂的场景,您将需要不同的行为.有时您希望将库与您的代码隔离开来(例如 eclipse 中的插件或应用程序服务器中的 Web 应用程序).
For more complex scenarios, you will need different behaviours. Sometimes you want to isolate a library from messing with your code (like plugins in eclipse or web applications in an application server).
将您的程序与其他类隔离的基本思想是使用额外的类加载器加载那些类并使用大量反射.如果您想阅读此内容,请查看 Oracle 在 ClassLoaders 或 OSGI.
The basic idea to isolate your program from other classes is to load those with an extra class loader and use a lot of reflection. If you want to read up on this have a look at Oracle's documentation on ClassLoaders or OSGI.
Tomcat(以及许多其他 Web 容器/应用程序服务器)使用单独的 ClassLoader 层次结构加载应用程序.这将所有类与其他(Web)应用程序隔离开来,从而确保单例、不同的类版本和所有这些东西不会发生冲突.
Tomcat (and a lot of other web containers / application servers) load the application with separate ClassLoader hierarchies. This isolates all classes against other (web) applications and thus also makes sure, that singletons, different class versions and all this stuff does not collide.
相关文章