大型应用中,系统是不能轻易停机的,一般选择升级都是选在晚上人少的时候进行停机维护。这样大大的降低了系统的可用性,也提高了系统维护的成本。因此如果能够实现在不停机的情况下能够进行系统的维护或者升级,则能够很好的解决上面的情况。在JAVA中我们可以利用CustomerClassLoader来实现以上机制。
在开始之前先简介一下JAVA中的ClassLoader机制。Java中类的实例化分为两部分:类的加载与类的实例化。而类的加载一般分为两种情况,显式加载和隐式加载。显示加载就是我们使用Class.forName而隐式加载的话就是我们平常使用最多的new.new关键字会在后台为我们做一些工作。
JAVA的类加载机制是分为几个层次来加载的。首先我们来看一下JAVA的加载器的层次结构:
1,BootStrapClassLoader是根加载器,它默认加载的是jre/lib目录下面的jar.或者是你在jdk的启动参数里面指定的:-XbootClasspath
2,ExtClassLoader加载器,它默认加载的是jre/lib/ext目录下面的jar,或者是启动参数里-Djava.ext.dirs 指定的目录
3,AppClassLoader加载器,它默认加载的是classpath变量指定的目录,其实就是我们应用程序的class目录。
4,CustomeClassLoader加载器,这是我们自已定义的加载器,必须要继承ClassLoader类。可以根据用户的需要定制自己的类加载过程,在运行期进行指定类的动态实时加载
而JDK的加载过程分为两个过程,第一步是:从下到上检查加载器的命名空间内(每个class在命名空间内只存在有一份)是否已有要加载的Class.如果找到则直接返回其引用,如果没有。则从上到下从各自的目录下去加载指定的class.如果到了最底层还没有加载成功。则抛出noclassfound的异常。其加载流程,详见如下图:
接下来,我们初步的了解了JDK的ClassLoader加载机制后,可见我们要实现动态的热布署,我们可以用CustomerClassLoader来实现我们的功能。自定义的ClassLoader需求要继承ClassLoader类。下面对于ClassLoader中的几个重要方法做一下介绍。
findLoadedClass:从当前类加载器的命名空间内查找指定的class,如果存在则返回其引用。不存在则返回null
getSystemClassLoader:调用系统使用的加载器,有时候我们自定义的类加载器可以调用它来执行一些其它的事情
resolveClass:链接一个指定的类,在某些情况下保证这个类一定可以用
defineClass:从class字节文件生成一个class对象
loadClass:加载类的入口方法,显式的加载类的方法。
下面我们看一下实现的自定义的类加载器:
在以上代码段中,我们在构造方法中,调用了super(null),这样的做法就是让我们定制的加载器的父加载器为null.这样避免我们定义的类被父加载器(AppClassLoader)抢先加载。在loadClass中我们首先从自已的类加载器的命名空间内查找要加载的类。如果没有找到。则让系统的加载器加载。
调用的类:
在以上类中,我们让系统每隔三秒种调用一次run程序。然后运行我们系统,可以看到控制台打出如下语句:
hello version 1
hello version 1
热下来我们不要停我们的应用,直接修改Foo的代码如下:
可见修改后打出如下语句:
hello version 1
hello version 1
hello version 1
hello version 2
hello version 2
代表已经替换成功了。
注意:有朋友会说为什么不把上面的反射的代码改成
这样呢,这样更明了,但是这种情况下。系统会报错:ClassCastException,因为你强转的时候的Foo是由AppClassLoader加载的,而我们的foo是由自定义的加载器加载的。在JDK中,继使两个类的类型相同,但是由不同的加载器加载的话。虚拟机也会认为这是不同的类型。但是我们可以通过接口来实现。是不会报错的,可以改成如下代码,则可以运行通过:
以上代码中Ifoo是Foo接口。
当然,要实现一个在线自动升级热布署的系统光靠上面这一点代码是不够的,还需要有完善的回退机制,检查机制等。但是以上部分做为core部分,基于以上部分是完全可以打造一个不停机升级的热布署应用。解决大型应用中的维护和升级的问题。
分享到:
相关推荐
这篇博客探讨了如何结合Classloader实现热部署。 首先,理解类加载器的工作机制至关重要。Java中的类加载分为五个阶段:加载、验证、准备、解析和初始化。每个类加载器都有自己的命名空间,避免了类名冲突。Java的...
接着,我们要介绍jreloader如何实现Tomcat的热部署。jreloader通过监听文件系统,一旦发现被监控的类文件发生变化,就会触发类的重新加载。它的工作原理是在Tomcat的生命周期中插入一个监听器,当检测到应用中的类...
总之,Java类热替换是一种强大的开发和调试工具,通过自定义ClassLoader和巧妙利用JVM特性,我们可以极大地提升开发效率。这个压缩包中的源码可能就是展示如何实现这个功能的一个实例,你可以仔细研究这些代码,加深...
综上所述,通过引入Spring Boot DevTools并配置相应的属性,开发者可以在STS中实现Spring Boot项目的热部署,从而提高开发效率。在了解了DevTools的工作原理后,开发者可以更好地利用这一工具,避免频繁的手动重启...
自定义ClassLoader允许开发者根据特定需求加载类,比如动态加载或更新类文件,这在某些高级应用场景中非常有用,如插件系统、热部署等。本案例将深入探讨如何创建一个自定义的ClassLoader,利用Java反射和注解技术...
对于工具的使用,可能是指开发者如何利用ClassLoader进行一些自定义操作,比如动态加载类、热部署等。例如,在开发插件化系统时,可能会创建自定义的ClassLoader,隔离不同插件的类加载,避免类冲突。 ClassLoader...
我们将深入探讨`ClassLoader`的工作原理,以及如何利用Java中的`ClassLoader`实现热部署。 首先,理解`ClassLoader`的基本概念。每个类在被JVM执行前,都必须由一个`ClassLoader`实例加载。Java中的类加载过程分为...
总的来说,Tomcat的热部署机制是通过自定义类加载器和字节码修改相结合的方式实现的,既能处理JSP的即时更新,也能适应业务类的动态调整。理解这个机制对于优化开发流程和提高生产环境的稳定性至关重要。
这个测试可能包含了如何利用类加载器实现热部署的技巧。 6. **类的可见性**:类加载器之间的关系也影响了类之间的可见性。同一类加载器加载的类可以互相访问,而不同类加载器加载的类之间默认不可见,除非使用`...
在实际应用中,动态部署和插件化可以结合使用,比如在ATLAS框架中,客户端可以实现动态替换和功能定制,通过插件化实现功能模块的热更新,同时利用动态部署实现整体应用的快速升级。在设计时,开发者需要考虑安全、...
通过自定义类加载器和利用ASM等字节码库,可以实现特定类的热部署,从而提高开发效率并减少系统中断的时间。然而,需要注意的是,这种做法可能会引入额外的复杂性和潜在的兼容性问题,因此在实际项目中需要谨慎使用...
例如,通过VFS,开发者可以方便地控制类库的加载路径,实现热部署,或者隔离不同应用程序的类空间,防止类版本冲突。 此外,Microcontainer的类加载层也支持OSGi的类加载概念,如束(Bundle)和上下文(Context),...
某些情况下,例如使用Spring框架,可以实现热部署,无需重启即可应用更新。 7. **日志记录与错误处理**:在整个更新过程中,确保记录日志并处理可能出现的错误,如网络中断、文件下载失败等。这样可以提供良好的...
此外,动态类加载机制在插件系统、框架(如Spring)、JMX(Java Management Extensions)和热部署等场景中都有广泛应用。例如,插件系统可以通过加载不同插件的类来扩展功能,而无需重新启动应用程序。 总之,Java...
Tomcat作为一个Web服务器,其类加载机制设计得相当灵活,以便支持不同Web应用之间的隔离和热部署。 Tomcat的类加载机制主要由以下几部分构成: 1. **Bootstrap ClassLoader**:这是JVM启动时的第一个类加载器,...
总结来说,Java类动态加载是一种强大的技术,可以用于实现插件系统、热部署等功能。通过自定义ClassLoader和利用`JavaCompiler` API,我们可以实现Java源文件的动态编译和加载,从而实现程序运行时的灵活扩展。在...
Java允许自定义ClassLoader,这在某些场景下非常有用,比如插件系统或者热部署。默认的类加载器层次结构包括Bootstrap ClassLoader、Extension ClassLoader和App ClassLoader,它们按照特定的顺序加载类。理解...
1. **热更新实现**:通过自定义ClassLoader,可以在不重启服务器的情况下,加载新的类文件替换旧的类文件。 2. **多租户隔离**:淘宝网存在大量的商户和服务,每个服务都可能有自己的类加载器,这样可以有效地隔离...
例如,自定义类加载器可以用于实现热部署、类隔离、加密加载等高级功能。 总的来说,ClassLoader是Java平台的核心组件之一,它的设计和实现对于理解JVM的工作原理至关重要。深入学习ClassLoader不仅可以提高编程...