3-tomcat部署多个项目互不影响-类加载器

Tomcat 上可以部署多个项目 Tomcat 的一般部署,可以通过多种方式启动一个 Tomcat 部署多个项目,那么 Tomcat 在设计时会遇到什么挑战呢?

Tomcat 运行时需要加载哪些类 ?
Tomcat 中的多个项目可能存在相同的类?
Tomcat 中类加载的挑战?

一、类加载类加载器

类加载类加载:主要是将.class 文件中的二进制字节读入到 JVM 中 我们可以看到因为这个定义,所以并没有规定一定是要磁盘加载文件,可以通过网络,内存什么的加载。只要是二进制流字节数据,JVM 就认。
类加载过程:
1.通过类的全限定名获取该类的二进制字节流;
2.将字节流所代表的静态结构转化为方法区的运行时数据结构
3.在内存中生成一个该类的 java.lang.Class 对象,作为方法区这个类的各种数据的访问入口
具体可查看另一篇
https://blog.csdn.net/lh87270202/article/details/102818008

二、tomcat类加载器

在这里插入图片描述

三、Webapp 类加载器

每个 web 应用会对一个 Context 节点,在 JVM 中就会对应一个 org.apache.catalina.core.StandardContext 对象,而每一个 StandardContext 对象内部都 一个加载器实例 loader 实例变量。这个 loader 实际上是 WebappLoader 对象。而每一个 WebappLoader 对象内部关联了一个 classLoader 变量(就这这个 类的定义中,可以看到该变量的类型是 org.apache.catalina.loader.WebappClassLoader)。 所以,这里一个 web 应用会对应一个 StandardContext 一个 WebappLoader 一个 WebappClassLoader
一个 web 应用对应着一个 StandardContext 实例,每个 web 应用都拥有独立 web 应用类加载器(WebappClassLoader),这个类加载器在 StandardContext.startInternal()中被构造了出来。
StandardContext启动方法,实现子类:
每个StandardContext对象都有一个自己的webappLoader

 @Override
protected synchronized void startInternal() throws LifecycleException {
    //Webapp类加载的设置
    //这里的获取和设置类加载
    if (getLoader() == null) {
         WebappLoader webappLoader = new WebappLoader(getParentClassLoader());
         webappLoader.setDelegate(getDelegate());
         setLoader(webappLoader);
     } 
}
四、Webapp 热加载
<context path="/" docBase="D:\work\code\test" reloadable="true"/>

在StandardContext启方法中,通过启一个线程,执行定时任务

 @Override
protected synchronized void startInternal() throws LifecycleException {
    // 启动ContainerBackgroundProcessor线程(容器后台线程)
     super.threadStart();
}

protected void threadStart() {
        if (thread != null)
            return;
        if (backgroundProcessorDelay <= 0)
            return;
        threadDone = false;
        String threadName = "ContainerBackgroundProcessor[" + toString() + "]";
        thread = new Thread(new ContainerBackgroundProcessor(), threadName);
        thread.setDaemon(true);
        thread.start();
    }   

ContainerBackgroundProcessor类,run方法:

/**
     * 执行定期任务,如重新加载等。此方法将在此容器的类加载上下文中调用。
     */
    @Override
    public void backgroundProcess() {
        if (reloadable && modified()) {
            try {
                //设置线程类加载器的类加载器 为WebappClassloader
                Thread.currentThread().setContextClassLoader
                    (WebappLoader.class.getClassLoader());
                if (context != null) {
                    //终要执行的重新加载的方法:StandardContext类的reload():
                    context.reload();
                }
            } finally {
                if (context != null && context.getLoader() != null) {
                    Thread.currentThread().setContextClassLoader
                        (context.getLoader().getClassLoader());
                }
            }
        }
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值