我遇到了一些Spring bean定义的问题。我有几个由我的main()方法加载的上下文xml文件,它们都包含几乎只有一个标记。当我的main方法启动时,我从Spring得到了这个错误:
Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'converterDAO' for bean class [my.package.InMemoryConverterDaoImpl] conflicts with existing, non-compatible bean definition of same name and class [my.other.package.StaticConverterDAOImpl]
两个DAO类都以这种方式注释:
@Repository("converterDAO")
public class StaticConverterDAOImpl implements ConverterDAO {
...
}
内存中的dao还有@Repository(" converterDAO")注释。 dao在其他类中被引用,如下所示:
...
private @Autowired @Qualifier("converterDAO") ConverterDAO converterDAO;
...
我想要一个DAO覆盖另一个DAO的定义,正如我一直认为的那样,这是首先使用DI框架的主要原因之一。多年来我一直用xml定义这样做,从来没有遇到任何问题。但是组件扫描和带注释的bean定义却不是这样吗?春天的意思是什么,当它说它们不兼容时#34 ;?它们实现相同的接口,并且它们被自动装配到该接口类型的字段中。为什么他们不相容?
有人可以为我提供一种方法,让一个带注释的,组件扫描的bean覆盖另一个吗?
-Mike
答案 0 :(得分:31)
在XML文件中,有一系列声明,您可以使用较新的声明覆盖先前的定义。使用注释时,之前或之后没有概念。所有豆子都处于同一水平。您定义了两个具有相同名称的bean,Spring不知道它应该选择哪个bean。
给他们一个不同的名称(例如 staticConverterDAO , inMemoryConverterDAO ),在Spring XML文件中创建一个别名(例如 theConverterDAO ) ,并在注入转换器时使用此别名:
@Autowired @Qualifier("theConverterDAO")
答案 1 :(得分:29)
我遇到了类似的问题,在一个项目中有两个jar库(app1和app2)。 bean“BeanName”在app1中定义,在app2中扩展,bean重新定义为同名。
在app1中:
package com.foo.app1.pkg1;
@Component("BeanName")
public class Class1 { ... }
在app2中:
package com.foo.app2.pkg2;
@Component("BeanName")
public class Class2 extends Class1 { ... }
由于相同的组件bean名称,这会导致加载applicationContext时出现ConflictingBeanDefinitionException
异常。
要解决此问题,请在Spring配置文件applicationContext.xml:
中解决<context:component-scan base-package="com.foo.app2.pkg2"/>
<context:component-scan base-package="com.foo.app1.pkg1">
<context:exclude-filter type="assignable" expression="com.foo.app1.pkg1.Class1"/>
</context:component-scan>
因此,Class1被排除在外自动进行组件扫描并分配给bean,避免名称冲突。
答案 2 :(得分:23)
我使用@RestController与Spring 4.x有类似的问题。两个不同的包有一个同名的类......
var data = "";
//show loading
//block all input
abc.abc(lat, long).then(function(x) {
data = x;
console.log(data);
// hide loading
// continue the process
});
console.log(data);
修复很容易......
package com.x.catalog
@RestController
public class TextureController {
...
package com.x.cms
@RestController
public class TextureController {
...
问题似乎是注释被自动装配并默认采用类名。在@RestController注释中给它一个显式名称允许你保留类名。
答案 3 :(得分:7)
我有类似的问题,这是因为我的一个bean最近被移动到另一个目录。我需要通过删除build/classes/java
目录来进行“构建清理”,问题就消失了。 (错误消息有两个不同的文件路径相互冲突,虽然我知道一个实际上不应该存在。)
答案 4 :(得分:0)
我正在开发一个多模块Gradle项目。
模块是:
- core,
- service,
- geo,
- report,
- util and
- some other modules.
因此,我们主要在 geo 模块中准备了一个组件[ locationRecommendHttpClientBuilder ]。
import org.springframework.stereotype.Component
@Component("locationRecommendHttpClientBuilder")
class LocationRecommendHttpClientBuilder extends PanaromaHttpClientBuilder {
@Override
PanaromaHttpClient buildFromConfiguration() {
this.setURL(PanaromaConf.getInstance().getString("locationrecommend.url"))
this.setMethod(PanaromaConf.getInstance().getString("locationrecommend.method"))
this.setProxyHost(PanaromaConf.getInstance().getString("locationrecommend.proxy.host"))
this.setProxyPort(PanaromaConf.getInstance().getInt("locationrecommend.proxy.port", 0))
return super.build()
}
}
<bean id="locationRecommendHttpClient"
class="au.co.google.panaroma.platform.logic.impl.PanaromaHttpClient"
scope="singleton" factory-bean="locationRecommendHttpClientBuilder"
factory-method="buildFromConfiguration" />
然后决定在核心模块中添加此组件。
一位工程师之前有 geo 模块的代码,然后他采用了核心的最新模块,但他忘了采用最新的 geo 模块。
因此组件[ locationRecommendHttpClientBuilder ]在他的项目中是双倍的,并且他收到以下错误。
Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'LocationRecommendHttpClientBuilder' for bean class [au.co.google.app.locationrecommendation.builder.LocationRecommendHttpClientBuilder] conflicts with existing, non-compatible bean definition of same name and class [au.co.google.panaroma.platform.logic.impl.locationRecommendHttpClientBuilder]
从 geo 模块中删除组件后,组件[ locationRecommendHttpClientBuilder ]仅在核心模块中可用。所以没有冲突的情况。通过这种方式解决问题。
答案 5 :(得分:0)
我也有类似的问题。我再次构建了项目,问题已解决。
原因是,在文件中已经为注释指定的Bean名称定义了序列。当我们对该bean名称进行更改并尝试运行该应用程序时,Spring无法识别该选择哪个。这就是为什么它显示此错误的原因。
就我而言,我从项目中删除了先前的bean类,并将相同的bean名称添加到了新的bean类中。因此,Spring对文件中已删除的Bean类具有先前的定义,并且在编译时与新添加的类冲突。因此,如果您进行“内部清理”,则将删除先前对Bean类的定义,并且编译将成功。
答案 6 :(得分:0)
当我在工作区中导入两个项目时遇到了这个问题。它以某种方式创建了一个不同的jar,因此我们可以删除jar和类文件,然后再次构建项目以正确获得依赖关系。
答案 7 :(得分:0)
有时候,如果您移动了类并且它引用了旧类,即使它们不存在,也会出现此问题。
在这种情况下,只需执行以下操作:
mvn eclipse:clean
mvn eclipse:eclipse
这对我来说很好。
答案 8 :(得分:0)
如果没有其他答案可以解决您的问题,并且在直接或间接更改任何配置(通过git pull / merge / rebase)后开始出现问题,并且您的项目是Maven项目:
mvn clean
希望这可以解决您的问题。还是有人
答案 9 :(得分:0)
使用Eclipse,我已经将类移到了新软件包中,并且出现了此错误。对我有用的是在做: 项目>清理
并通过右键单击它并选择 clean
来清洁我的TomCat服务器。感谢李洛克(Rock Lee)的回答,帮助我弄清楚了:)
答案 10 :(得分:0)
解释内部针对此错误
您会收到此错误,因为在实例化之后,容器尝试将相同的对象分配给两个类,因为类名是相同的,而与不同的包无关,这就是为什么错误表示不兼容的同名bean定义。
实际上,它是如何在内部工作的--- >>>>。
pkg test1; …。 @RestController 测试类{}
pkg test2; …。 @RestController 测试类{}
第一个容器将获得Test类,并且@RestController表示要实例化为…test = new Test();而且不会实例化两次 实例化后,容器将为两个类提供引用变量test(与类名相同),同时提供测试引用 对于第二类,它得到同名的不兼容bean定义……
解决方案— >>>>
为两个rest控制器分配一个引用名称,这样容器就不会使用默认名称实例化,并且对于这两个类而言,都不会高效地实例化 同名
例如->>>
pkg test1; …。 @RestController(“ test1”) 测试类{}
pkg test2; …。 @RestController(“ test2”) 测试类{}
注意:@ Controller,@ Service,@ Repository等也可以使用。
注意:如果要在类级别创建参考变量,则还可以使用@Qualifier(“特定参考名称”)进行注释。 @Autowired @Qualifier(“ test1”) 测试测试;
答案 11 :(得分:0)
我有同样的问题。我通过以下步骤解决了此问题(编辑器: IntelliJ ):
答案 12 :(得分:-1)
Eclipse上的gradle刷新项目为我解决了这个问题