【发布时间】:2014-05-13 09:15:19
【问题描述】:
我花了几天时间修复我的 Spring 项目中的错误。很长一段时间以来,我在错误日志中的主要问题是:
Bean already exists
我有两个文件:
WEB-INF/myproject-servlet.xml
WEB-INF/web.xml
在第一个中,我可以输入以下内容(假设我有一个管理动物园动物的应用程序):
<context:component-scan base-package="com.my.package.animals" />
这样(据我所知)我们正在启用 Spring bean 自动发现。所以现在,当我们运行我们的应用程序时,Spring 将从这个包中获取所有类,稍后它将遍历 resources 目录中的所有配置文件并初始化所有 bean(放置在与给定包关联的配置文件中) .
第二个,web.xml 包含这样的行
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/myproject-servlet.xml</param-value>
</context-param>
我还可以放置我的配置文件的路径,例如:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:animals-config.xml</param-value>
</context-param>
所以现在,我在 myproject-servlet.xml 中有“自动检测”,我在 web.xml 中有 context-param 用于相同的对象。
我的问题是,错误 "Bean already exists" 是否可能来自此?我几乎可以肯定,是的,我检查了所有 bean id 并且没有重复。
所以我还有一个问题。这样做的好方法是什么?当我创建新的配置文件时,我应该在哪里通知我的应用程序?在myproject-servlet.xml 或web.xml。我真的需要清理我的应用程序,我将从它开始。
我检查了一些示例,人们宁愿不要在web.xml 文件Simple example 中放置多个<context-param>
提前谢谢你
好的,我真的很接近解决我的问题了。
假设我有两个包:
com.my.pckg.a
com.my.pckg.b
类
com.my.pckg.a.ClassA
com.my.pckg.b.ClassB
我在myproject-servlet.xml 中添加了以下行:
<context:component-scan base-package="com.my.pckg.a" />
我有一个配置文件 myconfig.xml,里面有基于类 ClassA 和 ClassB 的 bean。
假设我们有如下 id 的 bean:
ClassA: ida1, ida2
ClassB: idb1, idb2
所以,我正在运行我的码头服务器,问题是:
哪些 bean 将被初始化?我只声明了包 com.my.pckg.a,所以从 myconfig.xml 开始,spring 应该只加载 ida1 和 ida2 但这个文件还包括另一个类的 bean .
那么最后...?
最后,我想我发现了一个问题。在web.xml 文件中我有一行:
<context:component-scan base-package="com.dirty.pckg" />
在这个包中,我有一个带有@Controller 注释的类DirtyClass。该类的字段之一是:
private static ApplicationContext context = new ClassPathXmlApplicationContext("dirty-config.xml");
所以,当我的应用程序启动时,Spring 使用DirtyClass(因为它有@)并映射它。因为 os static 上下文修饰符触发读取 dirty-config.xml。这就是我无法理解为什么我的代码会以奇怪的方式表现的方式。
【问题讨论】:
-
你的 animals-config.xml 中有什么?如果您的 bean 定义与 myproject-servlet.xml 中的相同,并将两者都声明为 contextConfigLocation,则可能是一个问题。
-
其实我改了很多东西,现在,这个案例不存在,也没有错误。最后,我想重点谈谈我的第二个问题。
myproject-servlet.xml和web.xml中应该是什么(考虑到“春天的味道”)?