V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  IDAEngine  ›  全部回复第 7 页 / 共 80 页
回复总数  1585
1 ... 3  4  5  6  7  8  9  10  11  12 ... 80  
镜像节点
2FAS APP
T mobile 套餐 0 元
上不锈钢的吧,木材的肯定会发霉
最好还是先去类似的公司去了解学习下经营模式,直接搞-试错风险大
156 天前
回复了 nuo7mi7 创建的主题 问与答 27 岁,感觉活的毫无激情,啥都没兴趣
@keian 看来也是看透了爱情的真相了,觉醒了
156 天前
回复了 nuo7mi7 创建的主题 问与答 27 岁,感觉活的毫无激情,啥都没兴趣
没事的,人生就那么长,多体验一下这个世界就行了,年龄增加后时间本身就是流失的越来越快的
159 天前
回复了 zhangjiashu2023 创建的主题 iPhone iPhone 去广告优雅的方式
Ad block one ,趋势科技开发的,挺好用的
1.了解 Tomcat 类加载:
Tomcat 使用分层类加载模型,不同的类加载器负责从不同位置加载类:
Bootstrap 类加载器:加载核心 Java 类。
系统类加载器:从 CLASSPATH 加载类。
公共类加载器:加载所有网络应用程序共享的类。
网络应用程序类加载器:加载每个网络应用程序的特定类。

2.选择方法:
在 Tomcat 中加载自定义类有两种主要方法:

a) WEB-INF/lib 中的自定义类加载器:
这种方法是在网络应用程序中创建自定义类加载器,并将其置于 WEB-INF/lib 目录中。这种方法可提供特定于应用程序的控制。

b) catalina.properties 中的自定义类加载器:
这种方法是使用 catalina.properties 文件为 Tomcat 全局配置自定义类加载器。这种方法会影响所有已部署的应用程序。

3.实施自定义类加载器:
无论选择哪种方法,核心逻辑都是一样的:

public class MyCustomClassLoader extends URLClassLoader {

public MyCustomClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent);
}

@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
// 1. Check if class is already loaded
Class<?> loadedClass = findLoadedClass(name);
if (loadedClass != null) {
return loadedClass;
}

// 2. Custom logic to prioritize JARs
for (URL url : getURLs()) {
if (url.getFile().endsWith(".jar")) {
try (JarFile jarFile = new JarFile(new File(url.toURI()))) {
// 3. Iterate through entries in each JAR
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if (entry.getName().endsWith(".class") &&
entry.getName().replace('/', '.').substring(0, entry.getName().length() - 6).equals(name)) {
byte[] classBytes = loadClassData(jarFile, entry);
return defineClass(name, classBytes, 0, classBytes.length);
}
}
}
}
}

// 4. Delegate to parent if not found
return super.loadClass(name, resolve);
}

// Helper method to load class data from JAR
private byte[] loadClassData(JarFile jarFile, JarEntry entry) throws IOException {
try (InputStream is = jarFile.getInputStream(entry)) {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
return buffer.toByteArray();
}
}
}

4.配置 Tomcat (针对方法):

a) WEB-INF/lib 方法:

编译自定义类加载器并将其打包为 JAR 文件。
将 JAR 文件放到网络应用程序的 WEB-INF/lib 目录中。

b) catalina.properties 方法:
编译自定义类加载器并将其打包为 JAR 文件。
将 JAR 文件放到 Tomcat 的 lib 目录中。
编辑 catalina.properties 文件(位于 Tomcat 的 conf 目录中)并添加以下一行,用自定义类加载器的完全合格名称替换 com.example.MyCustomClassLoader:
loader.path=com.example.MyCustomClassLoader

5.自定义加载逻辑:

在自定义类加载器的 loadClass 方法中,可以实现优先加载 JAR 文件的逻辑。这可能包括
根据预定义顺序检查 JAR 文件名或路径。
根据 JAR 属性实施加权系统。
使用配置文件或系统属性确定加载顺序。

这种方法允许您通过自己的逻辑和顺序来控制类加载过程,从而自定义 Tomcat 如何加载目录中的 JAR 文件。
GPT:

一般来说,您不应该依赖 Tomcat 的 lib 目录中 JAR 文件的特定加载顺序。Java 的类加载机制并不保证特定的加载顺序,试图强制加载顺序可能会导致脆性和不可预测的行为。
但是,如果您绝对必须控制特定 JAR 文件的加载顺序(例如,由于库冲突或非常特定的初始化需求),以下是一些方法及其注意事项:
1.Manifest 中的类路径:
工作原理在网络应用程序 WAR 文件(位于 WEB-INF/classes/META-INF/)的 MANIFEST.MF 文件中,您可以指定一个 Class-Path 条目。该条目列出了应用程序所依赖的其他 JAR ,它们将按照指定的顺序加载。
例如
Manifest-Version: 1.0
类路径:library1.jar library2.jar
注意事项
这种方法只能控制网络应用程序加载其依赖项的顺序。它不会影响 Tomcat 在其全局 lib 目录中加载 JAR 的顺序。
如果管理不慎,它可能会导致 "JAR 地狱",尤其是复杂的依赖关系树。
2.Tomcat 的共享类加载器:
如何工作 Tomcat 有一个 "共享类加载器 "的概念,它从 $CATALINA_HOME/lib 目录中的 JAR 中加载类。从该目录加载 JAR 的顺序会受到操作系统文件系统中 JAR 列出顺序的影响。
注意事项
不建议使用这种方法,因为它会破坏部署在同一 Tomcat 实例上的其他应用程序。
它完全依赖于环境(依赖于文件系统顺序),因此不具备可移植性。
3.自定义类加载器(高级且有风险):
工作原理:您可以在网络应用程序中创建自定义类加载器,以受控顺序从特定 JAR 中加载类。这是一种非常高级的技术,需要深入了解 Java 的类加载机制。
注意事项
这种方法非常复杂,如果不仔细实施,很容易导致微妙的类加载问题。
它会使应用程序的架构和调试变得非常复杂。
为什么依赖加载顺序会产生问题?
易损坏:如果依赖于特定的 JAR 加载顺序,Tomcat 版本、操作系统甚至目录中文件顺序的变化都可能导致应用程序崩溃。
难以调试:当出现类加载问题时,诊断和修复是出了名的困难,尤其是当你以非常规的方式操作类路径时。
违背最佳实践:Java 的类加载系统旨在以稳健、可预测的方式处理依赖关系。试图规避这种机制往往会导致问题多于解决。
推荐方法:
与其试图强制执行特定的加载顺序,不如将重点放在以下方面:
依赖关系管理:使用 Maven 或 Gradle 等构建工具来管理应用程序的依赖关系。这些工具擅长解决冲突,并确保在 WAR 文件中包含正确版本的库。
隔离:将应用程序及其所有必要的依赖项打包到自己的 WAR 文件(或作为 "胖 JAR")中。这样可以确保您的应用程序有自己独立的类路径,避免与同一服务器上运行的其他应用程序发生冲突。
代码设计:如果可能,重构代码以消除对特定 JAR 加载顺序的需求。这可能需要使用接口和依赖注入将代码与具体实现解耦。
通过遵循这些最佳实践,您可以创建更健壮、可维护和可移植的 Java 网络应用程序。
买比亚迪秦 L 呀,代步用,便宜而且还可以偶尔跑一跑滴滴
164 天前
回复了 magic3584 创建的主题 北京 明年幼升小了,放弃北漂,求城市推荐
东北可以呀,去年冬天去哈尔滨旅游了一下,哈尔滨确实不错哦
1 ... 3  4  5  6  7  8  9  10  11  12 ... 80  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1043 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 56ms · UTC 23:07 · PVG 07:07 · LAX 15:07 · JFK 18:07
Developed with CodeLauncher
♥ Do have faith in what you're doing.