3

我们有一个门户应用程序,其中包含一个主要 Web 应用程序上下文和许多次要 Web 应用程序上下文 - 插件。目前(非常简化)Main 有自己的 spring 库,如果他们想使用 spring,插件也必须拥有它们。在公共/共享的 tomcat 上下文中,只有驱动程序和接口。

如果将 spring 库移动到关于 spring 可能间接使用或它们可能使用 spring 的其他库的公共上下文中,它会起作用吗?像休眠一样,因为应用程序正在使用 spring-tx 等。休眠也必须移动到公共/共享上下文吗?

你怎么看,其他方面是什么?从 spring 应用程序上下文的角度来看,这样会容易得多。

4

3 回答 3

0

@RichW 正确地指出将 Spring 库放在 Tomcat 的公共类加载器中是不好的做法。而且很有可能它不起作用。

Java 使用类加载器层次结构)。当请求类加载时,类加载器将在尝试使用它自己的类路径加载类之前递归地从它的父类加载器请求类。这个过程一直持续到根类加载器(称为引导类加载器)。这样,从父类加载器引用的类总是优先于在层次结构中更靠下的类加载器中引用的类。

需要注意的是,在这个过程中,类永远不会从子类加载器中加载。因此,Spring 所需的任何类也需要加载到公共类加载器中——包括 asm、log4j、commons-logging 和 cglib(所有这些都是 spring 所依赖的)。这将导致一大堆问题:特别是,在公共类路径中包含公共日志记录是整个世界的伤害

如果您确实设法启动了 Tomcat,那么在回收应用程序时您会遇到内存泄漏问题。在 tomcat 中,应用程序是使用传统的垃圾收集来卸载的,因此如果有任何东西对应用程序中的类进行了引用,该类随后被重新启动,那么该应用程序将不会获得垃圾收集。Spring 和日志框架是保存类引用的主要候选者,因此在几次应用程序重新启动后,您可能会遇到 OOM 错误。

安全地执行此操作的唯一方法是考虑使用完整的应用程序服务器(例如 JBoss AS)并将您的应用程序部署为 EAR。

于 2011-12-14T12:46:23.043 回答
0

如果您能够从 Tomcat 迁移到成熟的 Java EE 容器,那么一种选择是使用Bundled Optional Classes 机制将所有内容打包为EAR

然后,您将公共 JAR 从 WAR 中移出并移到 EAR 的顶层。

于 2011-09-27T08:26:44.273 回答
-1

是的,我知道这很诱人。是的,它可以工作。但是有些人认为将特定于应用程序或特定于框架的库放在应用服务器的共享库文件夹中是一种不好的做法,我同意。

在我看来,web-apps 应该包含它们自己的依赖项(app jars、framework jars 等)。框架也有依赖关系,通常需要多个具有特定版本的 jar。有时这些版本会更改,有时依赖项会更改。随着时间的推移,共享库文件夹将成为 jar 的厨房水槽,这可能会以不可预测的方式影响您的所有应用程序。

走共享库文件夹路线,您会获得一些最初的便利,但您会失去选择:一次只影响一个网络应用程序的选择。我建议你将你的 jars 保存在你的网络应用程序中,很好地包含并与其他网络应用程序分开。这将使它们更可靠,并且您会发现框架升级更容易处理。从长远来看,你会更快乐,我向你保证。

于 2011-09-15T23:50:31.397 回答