网站首页 > 技术文章 正文
1.ClasserLoader介绍?
classloader顾名思义,即是类加载。虚拟机把描述类的数据从class字节码文件加载到内存,并对数据进行检验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。了解java的类加载机制,可以快速解决运行时的各种加载问题并快速定位其背后的本质原因,也是解决疑难杂症的利器。因此学好类加载原理也至关重要。
内置类加载器
JVM 中内置了三个重要的ClassLoader:
- BootstrapClassLoader(启动类加载器):最顶层的加载类,由 C++实现,通常表示为 null,并且没有父级,主要用来加载 JDK 内部的核心类库( %JAVA_HOME%/lib目录下的 rt.jar、resources.jar、charsets.jar等 jar 包和类)以及被 -Xbootclasspath参数指定的路径下的所有类。
- ExtensionClassLoader(扩展类加载器):主要负责加载 %JRE_HOME%/lib/ext 目录下的 jar 包和类以及被 java.ext.dirs 系统变量所指定的路径下的所有类。
- AppClassLoader(应用程序类加载器):面向我们用户的加载器,负责加载当前应用 classpath 下的所有 jar 包和类。
除了这三种类加载器之外,用户还可以加入自定义的类加载器来进行拓展,以满足自己的特殊需求。就比如说,我们可以对 Java 类的字节码(.class文件)进行加密,加载时再利用自定义的类加载器对其解密。
2.代码工程
实验目标
实现加载外部jar包,并调用其中类方法
JarLoader
package com.et;
import java.net.URL;
import java.net.URLClassLoader;
import java.lang.reflect.Method;
import java.io.File;
public class JarLoader {
private URLClassLoader urlClassLoader;
// load JAR file
public void loadJar(String jarFilePath) throws Exception {
File jarFile = new File(jarFilePath);
URL jarUrl = jarFile.toURI().toURL();
urlClassLoader = new URLClassLoader(new URL[]{jarUrl}, this.getClass().getClassLoader());
System.out.println("JAR Loaded: " + jarFilePath);
}
//load class from JAR and invoke method
public void invokeClassMethod(String className, String methodName) throws Exception {
if (urlClassLoader != null) {
Class<?> loadedClass = urlClassLoader.loadClass(className);
Method method = loadedClass.getDeclaredMethod(methodName);
method.invoke(loadedClass.newInstance());
System.out.println("Method Invoked: " + methodName);
} else {
System.out.println("ClassLoader is null, load a JAR first.");
}
}
// unload JAR
public void unloadJar() throws Exception {
if (urlClassLoader != null) {
urlClassLoader.close(); // close ClassLoader
urlClassLoader = null; // let it recycle by jvm
System.out.println("JAR Unloaded.");
} else {
System.out.println("No JAR to unload.");
}
}
}
service(demo模块)
- 创建sevice类
- mvn install 打包成jar包
package com.et.demo.service;
public class MockService implements Service {
@Override
public void printVersion() {
System.out.println("11.0");
}
}
package com.et.demo.service;
public interface Service {
void printVersion();
}
以上只是一些关键代码,所有代码请参见下面代码仓库
代码仓库
- https://github.com/Harries/Java-demo(classloader)
3.测试
编写测试类
package com.et;
public class Main {
public static void main(String[] args) throws Exception {
JarLoader jarLoader = new JarLoader();
// load JAR
jarLoader.loadJar("D:\\IdeaProjects\\Java-demo\\demo\\target\\demo-1.0-SNAPSHOT.jar");
// invoke the method
jarLoader.invokeClassMethod("com.et.demo.service.MockService", "printVersion");
// unload JAR
jarLoader.unloadJar();
}
}
启动main方法,查看日志
JAR Loaded: D:\IdeaProjects\Java-demo\demo\target\demo-1.0-SNAPSHOT.jar
11.0
Method Invoked: printVersion
JAR Unloaded.
Disconnected from the target VM, address: '127.0.0.1:53226', transport: 'socket'
Process finished with exit code 0
4.引用
- https://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html
- http://www.liuhaihua.cn/archives/711389.html
猜你喜欢
- 2024-11-12 JDK9模块化知识和规则入门 jdk9 module
- 2024-11-12 如何有效开发Java 如何有效开发地理教材
- 2024-11-12 BI工具入门:如何做关系数据源的连接?
- 2024-11-12 对另外网段的渗透测试 对网络开展渗透性测试
- 2024-11-12 一些可以显著提高大型 Java 项目启动速度的尝试
- 2024-11-12 为什么Python通过Jar包的方式不能同时链接多个异构库?
- 2024-11-12 powerdesigner连接Oracle逆向生成pdm文件。
- 2024-11-12 「转」jar包冲突漏洞,同一份代码有的主机运行正常,有的失败
- 2024-11-12 openjdk编译缺jfxrt.jar的坑货 openjdk没有javac
- 2024-11-12 说一说 JPA + Oracle 项目启动时遇到一大坑,你碰到过吗?
你 发表评论:
欢迎- 614℃几个Oracle空值处理函数 oracle处理null值的函数
- 605℃Oracle分析函数之Lag和Lead()使用
- 594℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 591℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 585℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 579℃【数据统计分析】详解Oracle分组函数之CUBE
- 568℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 559℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
-
- PageHelper - 最方便的 MyBatis 分页插件
- 面试二:pagehelper是怎么实现分页的,
- MyBatis如何实现分页查询?(mybatis-plus分页查询)
- SpringBoot 各种分页查询方式详解(全网最全)
- 如何在Linux上运行exe文件,怎么用linux运行windows软件
- 快速了解hive(快速了解美国50个州)
- Python 中的 pyodbc 库(pydbclib)
- Linux搭建Weblogic集群(linux weblogic部署项目步骤)
- 「DM专栏」DMDSC共享集群之部署(一)——共享存储配置
- 故障分析 | MySQL 派生表优化(mysql pipe)
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- 前端获取当前时间 (50)
- Oracle RAC (76)
- oracle恢复 (77)
- oracle 删除表 (52)
- oracle 用户名 (80)
- oracle 工具 (55)
- oracle 内存 (55)
- oracle 导出表 (62)
- oracle约束 (54)
- oracle 中文 (51)
- oracle链接 (54)
- oracle的函数 (58)
- 前端调试 (52)
本文暂时没有评论,来添加一个吧(●'◡'●)