前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >tomcat自定义类加载器_开发者不可以自定义类加载器

tomcat自定义类加载器_开发者不可以自定义类加载器

作者头像
全栈程序员站长
发布2022-10-04 10:06:52
3110
发布2022-10-04 10:06:52
举报

大家好,又见面了,我是你们的朋友全栈君。


tomcat 自定义类加载器

***************

相关类与接口

WebappClassLoader

代码语言:javascript
复制
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

代码语言:javascript
复制
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;
}
...

***************

自定义类加载器

代码语言:javascript
复制
@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);
}
}

控制台输出

代码语言:javascript
复制
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)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年9月5日 下,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • tomcat 自定义类加载器
  • ***************
  • ***************
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档