【发布时间】:2013-06-06 11:02:11
【问题描述】:
在我的库FooLibrary.jar 中,Spring 实例化了类com.example.FooImpl,它有一个属性bars。我有很多 Bar 实例也由 Spring 实例化。一组条形图自动连接到FooImpl,如下所示:
@Component
public class FooImpl {
@Inject
private Set<Bar> bars;
在独立应用程序中,Spring 实例化Bar 实例,实例化FooImpl 实例,然后将FooImpl.bars 与Bars 的集合自动连接。它有效。
现在我在 Tomcat 内的 webapp 中运行相同的 Spring 配置。 FooLibrary.jar 位于 WEB-INF/lib 内部,一切都按上述方式继续工作。
问题是 Web 应用程序会使用 JavaCompiler、which can't find its dependencies for dynamically compiling 自动编译 somes 类,除非我将该库放在启动 Tomcat 路径上。当我将FooLibrary.jar 添加到 Tomcat 类路径(例如,在 Eclipse 内的 Tomcat 启动配置中,或者我假设 startup.sh 或 setclasspath.bat 如果单独运行 Tomcat)时,自动装配停止工作。
也就是说,当我的 web 应用启动时,Spring 会创建所有 Bar 实例,然后实例化 FooImpl,但从不自动连接 Bars 的集合到 FooImpl.bars。 知道为什么吗?
(我想知道这是否与 Spring ContextLoaderListener 从 webapp 类加载器启动,但 FooImpl 和 Bar 实例来自 Tomcat 类加载器有关?)
【问题讨论】:
-
发生这种情况时,FooLibrary.jar 是否也在 WEB-INF/lib 中?自动装配也可能由于不兼容的类型而失败(例如,在多个类加载器中加载的类。
-
是的,
FooLibrary也继续驻留在WEB-INF/lib中,并且确实必须继续存在,因为除了它在创建动态类中的作用之外,它还被 web 应用程序使用。此外,由于依赖关系,它由 Maven 自动放置在WEB-INF/lib中。有什么方法可以确保自动装配正确吗? -
好吧,既然您已经将 JAR 放在了 tomcat 的引导类路径中,那么它也必须对 webapp 可见(您不必将 JAR 放在 WEB-INF/lib 中)。您可以将提供的依赖项限定为不让 Maven 将其放在 WEB-INF/lib 中。
-
@Jukka,看来你是正确的,将罐子放在两个地方可以防止自动装配的发生。我可以通过从
WEB-INF/lib中删除 jar 来完成工作,您关于 Maven 范围的提示提醒我,我可以将依赖项标记为provided。如果您想将您的回复放在答案中,我可以将其标记为正确回复。感谢您对此的帮助。 -
我复制粘贴了我的 cmets 的摘要作为答案。很高兴能提供帮助。
标签: spring tomcat classpath autowired inject