ClassLoader

Bootstrap ClassLoader
核心类加载器,默认加载路径%JRE_HOME%lib。启动JVM时通过设置-Xbootclasspath可改变加载路径
-Xbootclasspath::完全取代默认的加载路径
-Xbootclasspath/a::拼接到默认的加载路径后面(常用)
-Xbootclasspath/p::拼接到默认的加载路径前面
例如:java -Xbootclasspath/a:”D:Program FilesJavajdk1.8.0_241libtools.jar” -jar xxx.jar
Extention ClassLoader
扩展类加载器,默认加载路径%JRE_HOME%libext。启动JVM时通过设置-Djava.ext.dirs可改变加载路径(覆盖默认的加载路径)
App ClassLoader
应用类加载器,加载classpath下的所有类
自定义类加载
双亲委派机制,也可继承java.net.URLClassLoader
package com.wyj.agent;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class MyClassLoader extends ClassLoader {
public String filePath;
public MyClassLoader(ClassLoader parent, String filePath) {
super(parent);
this.filePath = filePath;
}
@Override
public Class findClass(String name) {
name = name.replaceAll(".", "/");
byte[] data = loadClassData(name);
return defineClass(null, data, 0, data.length);
}
private byte[] loadClassData(String name) {
FileInputStream fis = null;
byte[] data = null;
try {
File file = new File(filePath + File.separator + name + ".class");
System.out.println(file.getAbsolutePath());
fis = new FileInputStream(file);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int ch = 0;
while ((ch = fis.read()) != -1) {
baos.write(ch);
}
data = baos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return data;
}
}
类卸载
- 类的所有实例已被GC
- 加载该类的ClassLoader已被GC
- 该类的Class对象没有在任何地方被引用
- JVM自带的三种类加载器加载的类不会被卸载
ClassPath
.号代表的是当前目录
缺省值
当前目录
java className
CLASSPATH
系统环境变量,设置后会覆盖缺省值
java className
-classpath
若设置该参数,则会覆盖缺省值以及CLASSPATH
java -classpath “.” className
-jar
CLASSPATH以及-classpath设置无效,只会以启动jar包为搜索范围(这也是为什么应用程序打包成可执行的jar包后,不管你怎么设置classpath都不能引用到第三方jar包的东西了),并且jar包里面的jar也无法被搜索
java -jar xxx.jar
引用第三方jar包的解决方案:
- 配置-Xbootclasspath
- 把第三方jar包放置到%JRE_HOME%libext目录下或者配置-Djava.ext.dirs
- 配置MANIFEST.MF文件中的Class-Path属性来引用第三方jar包
- 使用自定义类加载器
Manifest扩展机制
- 将第三方jar包copy到启动jar所在的目录或子目录下
- 编辑MANIFEST.MF文件中的Class-Path,例如:Class-Path: xxx1.jar lib/xxx2.jar
maven配置Class-Path
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<archive>
<manifest>
<Main-Class>com.wyj.agent.MyAgent</Main-Class>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>