《How Tomcat Works》读书笔记(八)Loader
2013-02-22 14:30
399 查看
Loader就是一个普通的Java类加载器。
Tomcat通过实现org.apache.catalina.Loader接口来定义Loader,一个servlet容器需要制定自己的
Loader。
servlet容器不应该信任servlet,如果容器使用系统类加载器,那么servlet可以"看见"CLASSPATH中的class.
在加载类时可以加入特定的规则
可以换成之前加载过的类
支持自动重加载(热部署):自定制的类加载器(S)使用另外一个线程一直检查servlet和它依赖的class(S负责加载的)的时间戳,当WEB-INF/classes或WEB-INF/lib目录中的类被改变时,重新加载之。只需实现org.apache.catalina.loader.Reloader接口
Java类加载器。
jvm从java1.2开始使用3个类加载器:启动类加载器(祖父 GF)、扩展类加载器(父亲 F)、系统类加载器(儿子 S)。
GF:由操作系统本地代码编写,负责加载JVM启动所需的类库,还负责加载Java核心类库(如java.lang.*、java.io.*)
F:负责加载在标准扩展目录中的类(/jdk/jre/lib/ext)
S:加载CLASSPATH中的类.
双亲委托模式:
当JVM要加载一个类时,S首先被调用,但S不会去直接加载这个类,他会委托给F,而F会委托给GF,如果GF没有找到这个类就让F去加载,如果F也没找到,就让S去加载。如果最后S也没找到,就会抛出java.lang.ClassNotFoundException异常。
双亲委托模式有效保证了类加载的安全性:
有人恶意写了一个java.lang.String类,希望能够替代java核心同名类,当String在程序某处被调用时,S委托F,F委托GF,GF会找到真正的Java核心库中的String类并加载,而恶意的String不会获得被加载的机会。
Web应用在加载servlet和其他class是要遵守规则的:
servlet只可以使用部署在WEB-INF/classes或其子目录下的class.放在WEB-INF/lib下的jar.
一个Tomcat的Loader代表的是一个Web应用加载器而不是一个类加载器.它必须实现org.apache.catalina.Loader接口.一个Loader的实现拥有一个类加载器(org.apache.catalina.loader.WebappClassLoader)并可以通过Loader接口中定义的getClassLoader方法获得它。
Loader通常会和一个Context(代表一个Web应用,也是一个容器)绑定在一起,通过Loader接口中定义的getContainer和setContainer方法,获得和设置Context.
重加载 如果Conext中的class被改变了,Loader(如果支持的话)会调用Context接口中定义的reload方法重新加载它们,而不需要重启Tomcat。Loader中定义了setReloadable和getReloadable来决定是否支持重加载。
默认的org.apache.catalina.core.StandardContext是不支持重加载的,如果想要支持,我们需要在server.xml添加一个Context元素:
<Context path="/myApp" docBase="myApp" debug="0" reloadable="true"/>
Loader接口定义
Tomcat提供了一个Loader的实现:org.apache.catalina.loader.WebappLoader
并且提供了它的类加载器实现:org.apache.catalina.loader.WebappClassLoader(继承了java.net.URLClassLoader类)
![](http://static.oschina.net/uploads/space/2013/0222/114112_dNby_926475.png)
Reloader接口
org.apache.catalina.loader.WebappLoader
创建一个类加载器
设置repositories仓库(可以理解为Loader去加载class的地方)
设置classpaht
设置权限
开启一个新线程来实现自动重加载(循环检查)
org.apache.catalina.loader.WebappClassLoader
缓存加载过的类
local cache:WebappClassLoader实例自己来管理
super cache:java.lang.ClassLoader管理了一个Vector(存之前加载过的类)来防止GC,由超类管理
加载类
检查local cache
检查super cache
检查repositories仓库 找到加载 找不到抛异常ClassNotFoundException
Tomcat通过实现org.apache.catalina.Loader接口来定义Loader,一个servlet容器需要制定自己的
Loader。
servlet容器不应该信任servlet,如果容器使用系统类加载器,那么servlet可以"看见"CLASSPATH中的class.
在加载类时可以加入特定的规则
可以换成之前加载过的类
支持自动重加载(热部署):自定制的类加载器(S)使用另外一个线程一直检查servlet和它依赖的class(S负责加载的)的时间戳,当WEB-INF/classes或WEB-INF/lib目录中的类被改变时,重新加载之。只需实现org.apache.catalina.loader.Reloader接口
Java类加载器。
jvm从java1.2开始使用3个类加载器:启动类加载器(祖父 GF)、扩展类加载器(父亲 F)、系统类加载器(儿子 S)。
GF:由操作系统本地代码编写,负责加载JVM启动所需的类库,还负责加载Java核心类库(如java.lang.*、java.io.*)
F:负责加载在标准扩展目录中的类(/jdk/jre/lib/ext)
S:加载CLASSPATH中的类.
双亲委托模式:
当JVM要加载一个类时,S首先被调用,但S不会去直接加载这个类,他会委托给F,而F会委托给GF,如果GF没有找到这个类就让F去加载,如果F也没找到,就让S去加载。如果最后S也没找到,就会抛出java.lang.ClassNotFoundException异常。
双亲委托模式有效保证了类加载的安全性:
有人恶意写了一个java.lang.String类,希望能够替代java核心同名类,当String在程序某处被调用时,S委托F,F委托GF,GF会找到真正的Java核心库中的String类并加载,而恶意的String不会获得被加载的机会。
Web应用在加载servlet和其他class是要遵守规则的:
servlet只可以使用部署在WEB-INF/classes或其子目录下的class.放在WEB-INF/lib下的jar.
一个Tomcat的Loader代表的是一个Web应用加载器而不是一个类加载器.它必须实现org.apache.catalina.Loader接口.一个Loader的实现拥有一个类加载器(org.apache.catalina.loader.WebappClassLoader)并可以通过Loader接口中定义的getClassLoader方法获得它。
Loader通常会和一个Context(代表一个Web应用,也是一个容器)绑定在一起,通过Loader接口中定义的getContainer和setContainer方法,获得和设置Context.
重加载 如果Conext中的class被改变了,Loader(如果支持的话)会调用Context接口中定义的reload方法重新加载它们,而不需要重启Tomcat。Loader中定义了setReloadable和getReloadable来决定是否支持重加载。
默认的org.apache.catalina.core.StandardContext是不支持重加载的,如果想要支持,我们需要在server.xml添加一个Context元素:
<Context path="/myApp" docBase="myApp" debug="0" reloadable="true"/>
Loader接口定义
public interface Loader { public ClassLoader getClassLoader(); public Container getContainer(); public void setContainer(Container container); public DefaultContext getDefaultContext(); public void setDefaultContext(DefaultContext defaultContext); public boolean getDelegate(); public void setDelegate(boolean delegate); public String getInfo(); public boolean getReloadable(); public void setReloadable(boolean reloadable); public void addPropertyChangeListener(PropertyChangeListener listener); public void addRepository(String repository); public String[] findRepositories(); public boolean modified(); public void removePropertyChangeListener(PropertyChangeListener listener); }
Tomcat提供了一个Loader的实现:org.apache.catalina.loader.WebappLoader
并且提供了它的类加载器实现:org.apache.catalina.loader.WebappClassLoader(继承了java.net.URLClassLoader类)
![](http://static.oschina.net/uploads/space/2013/0222/114112_dNby_926475.png)
Reloader接口
public interface Reloader { public void addRepository(String repository); public String[] findRepositories (); //true:支持重加载 public boolean modified(); }
org.apache.catalina.loader.WebappLoader
创建一个类加载器
设置repositories仓库(可以理解为Loader去加载class的地方)
设置classpaht
设置权限
开启一个新线程来实现自动重加载(循环检查)
org.apache.catalina.loader.WebappClassLoader
缓存加载过的类
local cache:WebappClassLoader实例自己来管理
super cache:java.lang.ClassLoader管理了一个Vector(存之前加载过的类)来防止GC,由超类管理
加载类
检查local cache
检查super cache
检查repositories仓库 找到加载 找不到抛异常ClassNotFoundException
相关文章推荐
- How tomcat works 读书笔记十五 Digester库 上
- How tomcat works 读书笔记十五 Digester库 下
- 《How Tomcat Works》读书笔记(四):容器初探
- 《How Tomcat Works》读书笔记(二):Connector
- how tomcat works 读书笔记九 Session管理
- how tomcat works 读书笔记 十一 StandWrapper 上
- how tomcat works 读书笔记 十一 StandWrapper 下
- How tomcat works 读书笔记十二 StandardContext 下
- How tomcat works 读书笔记十五 Digester库 上
- How tomcat works 读书笔记十五 Digester库 下
- how tomcat works 读书笔记九 Session管理
- 《How Tomcat Works》读书笔记(四):容器初探
- How tomcat works 读书笔记十二 StandardContext 下
- How tomcat works 读书笔记十三 Host和Engine
- 《How Tomcat Works》读书笔记(九)Session Management
- How tomcat works 读书笔记十二 StandardContext 上
- 《How Tomcat Works》读书笔记(四)Tomcat Default Connector
- How Tomcat Works 读书笔记 八 加载器 上
- How tomcat works 读书笔记十三 Host和Engine