大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
tomcat 自定义类加载器
***************
相关类与接口
WebappClassLoader
public class WebappClassLoader extends WebappClassLoaderBase {
public WebappClassLoader() {
}
public WebappClassLoader(ClassLoader parent) {
super(parent);
}
public WebappClassLoader copyWithoutTransformers() {
WebappClassLoader result = new WebappClassLoader(this.getParent());
super.copyStateWithoutTransformers(result);
try {
result.start();
return result;
} catch (LifecycleException var3) {
throw new IllegalStateException(var3);
}
}
protected Object getClassLoadingLock(String className) {
return this;
}
}
WebappClassLoaderBase
public abstract class WebappClassLoaderBase extends URLClassLoader implements Lifecycle, InstrumentableClassLoader, WebappProperties, PermissionCheck {
...
public Class<?> findClass(String name) throws ClassNotFoundException {
if (log.isDebugEnabled()) {
log.debug(" findClass(" + name + ")");
}
this.checkStateForClassLoading(name);
if (this.securityManager != null) {
int i = name.lastIndexOf(46);
if (i >= 0) {
try {
if (log.isTraceEnabled()) {
log.trace(" securityManager.checkPackageDefinition");
}
this.securityManager.checkPackageDefinition(name.substring(0, i));
} catch (Exception var8) {
if (log.isTraceEnabled()) {
log.trace(" -->Exception-->ClassNotFoundException", var8);
}
throw new ClassNotFoundException(name, var8);
}
}
}
Class clazz = null;
try {
if (log.isTraceEnabled()) {
log.trace(" findClassInternal(" + name + ")");
}
try {
if (this.securityManager != null) {
PrivilegedAction<Class<?>> dp = new WebappClassLoaderBase.PrivilegedFindClassByName(name);
clazz = (Class)AccessController.doPrivileged(dp);
} else {
clazz = this.findClassInternal(name); //web类加载器先加载类
}
} catch (AccessControlException var4) {
log.warn(sm.getString("webappClassLoader.securityException", new Object[]{name, var4.getMessage()}), var4);
throw new ClassNotFoundException(name, var4);
} catch (RuntimeException var5) {
if (log.isTraceEnabled()) {
log.trace(" -->RuntimeException Rethrown", var5);
}
throw var5;
}
if (clazz == null && this.hasExternalRepositories) {
try {
clazz = super.findClass(name); //查找不到,调用父类加载器加载类
} catch (AccessControlException var6) {
log.warn(sm.getString("webappClassLoader.securityException", new Object[]{name, var6.getMessage()}), var6);
throw new ClassNotFoundException(name, var6);
} catch (RuntimeException var7) {
if (log.isTraceEnabled()) {
log.trace(" -->RuntimeException Rethrown", var7);
}
throw var7;
}
}
if (clazz == null) {
if (log.isDebugEnabled()) {
log.debug(" --> Returning ClassNotFoundException");
}
throw new ClassNotFoundException(name);
}
} catch (ClassNotFoundException var9) {
if (log.isTraceEnabled()) {
log.trace(" --> Passing on ClassNotFoundException");
}
throw var9;
}
if (log.isTraceEnabled()) {
log.debug(" Returning class " + clazz);
}
if (log.isTraceEnabled()) {
ClassLoader cl;
if (Globals.IS_SECURITY_ENABLED) {
cl = (ClassLoader)AccessController.doPrivileged(new WebappClassLoaderBase.PrivilegedGetClassLoader(clazz));
} else {
cl = clazz.getClassLoader();
}
log.debug(" Loaded by " + cl.toString());
}
return clazz;
}
protected Class<?> findClassInternal(String name) {
this.checkStateForResourceLoading(name);
if (name == null) {
return null;
} else {
String path = this.binaryNameToPath(name, true);
ResourceEntry entry = (ResourceEntry)this.resourceEntries.get(path);
WebResource resource = null;
if (entry == null) {
resource = this.resources.getClassLoaderResource(path);
if (!resource.exists()) {
return null;
}
entry = new ResourceEntry();
entry.lastModified = resource.getLastModified();
synchronized(this.resourceEntries) {
ResourceEntry entry2 = (ResourceEntry)this.resourceEntries.get(path);
if (entry2 == null) {
this.resourceEntries.put(path, entry);
} else {
entry = entry2;
}
}
}
Class<?> clazz = entry.loadedClass;
if (clazz != null) {
return clazz;
} else {
synchronized(JreCompat.isGraalAvailable() ? this : this.getClassLoadingLock(name)) {
clazz = entry.loadedClass;
if (clazz != null) {
return clazz;
} else {
if (resource == null) {
resource = this.resources.getClassLoaderResource(path);
}
if (!resource.exists()) {
return null;
} else {
byte[] binaryContent = resource.getContent();
if (binaryContent == null) {
return null;
} else {
Manifest manifest = resource.getManifest();
URL codeBase = resource.getCodeBase();
Certificate[] certificates = resource.getCertificates();
String packageName;
if (this.transformers.size() > 0) {
packageName = path.substring(1, path.length() - ".class".length());
Iterator var12 = this.transformers.iterator();
while(var12.hasNext()) {
ClassFileTransformer transformer = (ClassFileTransformer)var12.next();
try {
byte[] transformed = transformer.transform(this, packageName, (Class)null, (ProtectionDomain)null, binaryContent);
if (transformed != null) {
binaryContent = transformed;
}
} catch (IllegalClassFormatException var18) {
log.error(sm.getString("webappClassLoader.transformError", new Object[]{name}), var18);
return null;
}
}
}
packageName = null;
int pos = name.lastIndexOf(46);
if (pos != -1) {
packageName = name.substring(0, pos);
}
Package pkg = null;
if (packageName != null) {
pkg = this.getPackage(packageName);
if (pkg == null) {
try {
if (manifest == null) {
this.definePackage(packageName, (String)null, (String)null, (String)null, (String)null, (String)null, (String)null, (URL)null);
} else {
this.definePackage(packageName, manifest, codeBase);
}
} catch (IllegalArgumentException var17) {
}
pkg = this.getPackage(packageName);
}
}
if (this.securityManager != null && pkg != null) {
boolean sealCheck = true;
if (pkg.isSealed()) {
sealCheck = pkg.isSealed(codeBase);
} else {
sealCheck = manifest == null || !this.isPackageSealed(packageName, manifest);
}
if (!sealCheck) {
throw new SecurityException("Sealing violation loading " + name + " : Package " + packageName + " is sealed.");
}
}
try {
clazz = this.defineClass(name, binaryContent, 0, binaryContent.length, new CodeSource(codeBase, certificates));
} catch (UnsupportedClassVersionError var16) {
throw new UnsupportedClassVersionError(var16.getLocalizedMessage() + " " + sm.getString("webappClassLoader.wrongVersion", new Object[]{name}));
}
entry.loadedClass = clazz;
return clazz;
}
}
}
}
}
}
}
public void start() throws LifecycleException {
this.state = LifecycleState.STARTING_PREP;
WebResource[] classesResources = this.resources.getResources("/WEB-INF/classes");
//加载的resource资源路径
WebResource[] jars = classesResources;
int var3 = classesResources.length;
int var4;
for(var4 = 0; var4 < var3; ++var4) {
WebResource classes = jars[var4];
if (classes.isDirectory() && classes.canRead()) {
this.localRepositories.add(classes.getURL());
}
}
jars = this.resources.listResources("/WEB-INF/lib");
//加载的jar包资源路径
WebResource[] var7 = jars;
var4 = jars.length;
for(int var8 = 0; var8 < var4; ++var8) {
WebResource jar = var7[var8];
if (jar.getName().endsWith(".jar") && jar.isFile() && jar.canRead()) {
this.localRepositories.add(jar.getURL());
this.jarModificationTimes.put(jar.getName(), jar.getLastModified());
}
}
this.state = LifecycleState.STARTED;
}
...
***************
自定义类加载器
@Data
class Person{
private String name;
private Integer age;
}
class CustomLoader extends ClassLoader{
private String loadPath;
private final String loaderName = "customLoader";
public CustomLoader(String loadPath){
this.loadPath = loadPath;
}
public CustomLoader(ClassLoader parent, String loadPath){
super(parent);
this.loadPath = loadPath;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
byte[] data = getClassData(name);
return defineClass(name, getClassData(name),0, data.length);
}catch (Exception e){
throw new ClassNotFoundException();
}
}
private byte[] getClassData(String name) throws Exception{
String path;
String suffix = ".class";
int index = name.lastIndexOf(".");
name = name.substring(index+1);
if (loadPath.endsWith("/")){
path = loadPath + name + suffix;
}else {
path = loadPath + File.separator + name + suffix;
}
FileInputStream inputStream = new FileInputStream(path);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
byte[] data = new byte[1024];
int size = 0;
while ((size = inputStream.read(data))!=-1){
outputStream.write(data, 0, size);
}
return outputStream.toByteArray();
}catch (Exception e){
e.printStackTrace();
}finally {
try {
inputStream.close();
outputStream.close();
}catch (Exception e){
e.printStackTrace();
}
}
throw new ClassNotFoundException();
}
@Override
public String toString() {
return "CustomLoader{" +
"loaderName='" + loaderName + '\'' +
'}';
}
}
public class LoaderTest {
private static final String loadPath = "./custom";
public static void main(String[] args) throws Exception{
CustomLoader customLoader = new CustomLoader(null, loadPath);
fun(customLoader, "com.example.demo.test.Person");
CustomLoader customLoader2 = new CustomLoader(loadPath);
fun2(customLoader2, "com.example.demo.test.Person");
}
private static void fun(CustomLoader customLoader, String className) throws Exception{
Class<?> person = customLoader.loadClass(className);
System.out.println("customLoader.loadClass(className):"+person.getClassLoader());
System.out.println("Person.class.getClassLoader():"+Person.class.getClassLoader()+"\n");
}
private static void fun2(CustomLoader customLoader, String className) throws Exception{
Class<?> person = customLoader.loadClass(className);
System.out.println("customLoader.loadClass(className):"+person.getClassLoader());
System.out.println("Person.class.getClassLoader():"+Person.class.getClassLoader());
Person object = (Person)person.getConstructor().newInstance();
Method name = person.getDeclaredMethod("setName", String.class);
name.invoke(object,"瓜田李下");
Method age = person.getDeclaredMethod("setAge", Integer.class);
age.invoke(object, 20);
System.out.println(object);
}
}
控制台输出
customLoader.loadClass(className):CustomLoader{loaderName='customLoader'}
Person.class.getClassLoader():sun.misc.Launcher$AppClassLoader@18b4aac2
customLoader.loadClass(className):sun.misc.Launcher$AppClassLoader@18b4aac2
Person.class.getClassLoader():sun.misc.Launcher$AppClassLoader@18b4aac2
Person(name=瓜田李下, age=20)
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/196931.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...