Tomcat之类加载器6

本文深入探讨了Tomcat的类加载器,特别是WebappLoader和WebappClassLoader的实现。Java类加载遵循双亲委派模型,而Tomcat的Loader接口确保了Web应用类的特定加载规则,如限制访问路径。WebappLoader创建自定义类加载器,设置仓库和权限,并支持类的动态重载。WebappClassLoader则负责高效地加载Web应用的类,通过缓存提高性能并确保安全性。Tomcat的类加载结构旨在实现应用隔离、资源共享和JSP动态更新。
摘要由CSDN通过智能技术生成

Java类加载双亲委派模型

Java类加载器是用户程序和JVM虚拟机之间的桥梁,在Java程序中起了至关重要的作用。java中的类加载默认是采用双亲委派模型,即加载一个类时,首先判断自身define加载器有没有加载过此类,如果加载了直接获取class对象,如果没有查到,则交给加载器的父类加载器去重复上面过程。

[图片上传失败...(image-90f506-1649066618764)]

Loader接口

在载入Web应用程序中需要的servlet类及其相关类时要遵守一些明确的规则,例如应用程序中的servlet只能引用部署在WEB-INF/classes目录及其子目录下的类。但是,servlet类不能访问其它路径中的类,即使这些累包含在运行当前Tomcat的JVM的CLASSPATH环境变量中。此外,servlet类只能访问WEB-INF/LIB目录下的库,其它目录的类库均不能访问。Tomcat中的载入器值得是Web应用程序载入器,而不仅仅是类载入器,载入器必须实现Loader接口。Loader接口的定义如下所示:

public interface Loader {

    public void backgroundProcess();
    public ClassLoader getClassLoader();
    public Context getContext();
    public void setContext(Context context);
    public boolean getDelegate();
    public void setDelegate(boolean delegate);
    public void addPropertyChangeListener(PropertyChangeListener listener);
    public boolean modified();
    public void removePropertyChangeListener(PropertyChangeListener listener);
}

后台任务:Loader接口需要进行在servlet类变更的时候实现类的重新加载,这个任务就是在backgroundProcess()中实现的,WebApploader中backgroundProcess()的实现如下所示。可以看到,当Context容器开启了Reload功能并且仓库变更的情况下,Loaders会先把类加载器设置为Web类加载器,重启Context容器。重启Context容器会重启所有的子Wrapper容器,会销毁并重新创建servlet类的实例,从而达到动态加载servlet类的目的。

    @Override
    public void backgroundProcess() {
        Context context = getContext();
        if (context != null) {
            if (context.getReloadable() && modified()) {
                ClassLoader originalTccl = Thread.currentThread().getContextClassLoader();
                try {
                    Thread.currentThread().setContextClassLoader(WebappLoader.class.getClassLoader());
                    context.reload();
                } finally {
                    Thread.currentThread().setContextClassLoader(originalTccl);
                }
            }
        }
    }

类加载器:Loader的实现中,会使用一个自定义类载入器,它是WebappClassLoader类的一个实例。可以使用Loader接口的getClassLoader()方法来获取Web载入器中的ClassLoader的实例。默认的类加载器的实现有两种种:ParallelWebappClassLoader和WebappClassLoader

Context容器:Tomcat的载入器通常会与一个Context级别的servelt容器相关联,Loader接口的getContainer()方法和setContainer()方法用来将载入器和某个servlet容器关联。如果Context容器中的一个或者多个类被修改了,载入器也可以支持对类的重载。这样,servlet程序员就可以重新编译servlet类及其相关类,并将其重新载入而不需要重新启动Tomcat。Loader接口使用modified()方法来支持类的自动重载。

类修改检测:在载入器的具体实现中,如果仓库中的一个或者多个类被修改了,那么modified()方法必须放回true,才能提供自动重载的支持

父载入器:载入器的实现会指明是否要委托给父类的载入器,可以通过setDelegate()和getDelegate方法配置。

WebappLoader类

Tomcat中唯一实现Loader接口的类就是WebappLoader类,其实例会用作Web应用容器的载入器,负责载入Web应用程序中所使用的类。在容器启动的时候,WebApploader会执行以下工作:

  • 创建类加载器
  • 设置仓库
  • 设置类的路径
  • 设置访问权限
  • 启动新线程来支持自动重载

创建类加载器

为了完成类加载功能,WebappLoader会按照配置创建类加载器的实例,Tomcat默认有两种类加载器:WebappClassLoader和ParallelWebappClassLoader,默认情况下使用ParallelWebappClassLoader作为类加载器。用户可以通过setLoaderClass()设置类加载器的名称。WebappLoader创建类加载器的源码如下所示,我们可以看到类加载器的实例必须是WebappClassLoaderBase的子类。

    private WebappClassLoaderBase createClassLoader()
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值