83 votes

Le nom du bean spécifié par l'annotation est en conflit avec un bean existant, non compatible.

J'ai un problème avec certaines définitions de Spring bean. J'ai quelques fichiers xml de contexte qui sont chargés par ma méthode main(), et les deux contiennent presque exclusivement une balise. Lorsque ma méthode principale démarre, j'obtiens cette erreur de 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]

Les deux classes DAO sont annotées de cette manière :

@Repository("converterDAO")
public class StaticConverterDAOImpl implements ConverterDAO {
...
}

Le dao en mémoire possède également l'annotation @Repository("converterDAO"). Le dao est référencé dans d'autres classes comme celle-ci :

...
private @Autowired @Qualifier("converterDAO") ConverterDAO converterDAO;
...

Je veux qu'un DAO remplace la définition de l'autre, ce qui, d'après ce que j'ai toujours compris, est l'une des principales raisons d'utiliser un cadre DI en premier lieu. Je fais cela avec des définitions xml depuis des années et je n'ai jamais eu de problèmes. Mais ce n'est pas le cas avec les scans de composants et les définitions de beans annotées ? Et que veut dire Spring lorsqu'il affirme qu'ils ne sont pas "compatibles" ? Ils implémentent la même interface, et ils sont autowired dans les champs qui sont de ce type d'interface. Pourquoi diable ne sont-ils pas compatibles ?

Quelqu'un peut-il me fournir un moyen pour qu'un haricot annoté et balayé par des composants puisse en remplacer un autre ?

-Mike

49voto

inewland53 Points 11

J'ai eu un problème similaire avec Spring 4.x en utilisant @RestController. Deux paquets différents avaient une classe avec le même nom...

package com.x.catalog

@RestController
public class TextureController {
...

package com.x.cms
@RestController
public class TextureController {
...

La réparation a été facile...

package com.x.catalog

@RestController("CatalogTextureController")
public class TextureController {
...

package com.x.cms
@RestController("CMSTextureController")
public class TextureController {
...

Le problème semble être que l'annotation se fait automatiquement et prend le nom de la classe par défaut. Lui donner un nom explicite dans l'annotation @RestController permet de conserver les noms de classe.

39voto

JB Nizet Points 250258

Dans un fichier XML, il y a une séquence de déclarations, et vous pouvez remplacer une définition précédente par une nouvelle. Lorsque vous utilisez des annotations, il n'y a pas de notion de antes de ou après . Tous les haricots sont au même niveau. Vous avez défini deux beans avec le même nom, et Spring ne sait pas lequel il doit choisir.

Donnez-leur un nom différent ( staticConverterDAO , inMemoryConverterDAO par exemple), créer un alias dans le fichier Spring XML ( theConverterDAO par exemple), et utiliser cet alias lors de l'injection du convertisseur :

@Autowired @Qualifier("theConverterDAO")

38voto

user1897261 Points 381

J'ai eu un problème similaire, avec deux bibliothèques jar (app1 et app2) dans un projet. Le bean "BeanName" est défini dans app1 et est étendu dans app2 et le bean redéfini avec le même nom.

Dans l'app1 :

package com.foo.app1.pkg1;

@Component("BeanName")
public class Class1 { ... }

Dans l'app2 :

package com.foo.app2.pkg2;

@Component("BeanName")
public class Class2 extends Class1 { ... }

Il en résulte que le ConflictingBeanDefinitionException exception lors du chargement de l'applicationContext en raison du même nom de bean de composant.

Pour résoudre ce problème, dans le fichier de configuration de 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>

Ainsi, la classe 1 est exclue pour être automatiquement analysée et affectée à un haricot, ce qui évite le conflit de noms.

32voto

Rock Lee Points 130

J'ai eu un problème similaire, et c'était parce qu'un de mes haricots avait été déplacé dans un autre répertoire récemment. J'ai dû faire un "build clean" en supprimant le fichier build/classes/java et le problème a disparu. (Le message d'erreur indiquait que les deux chemins d'accès aux fichiers étaient en conflit l'un avec l'autre, alors que je savais que l'un d'entre eux ne devait plus exister).

13voto

Snehal Masne Points 406

Le problème survient parfois lorsque vous avez déplacé vos classes et qu'il est fait référence à d'anciennes classes, même si elles n'existent pas.

Dans ce cas, il suffit de faire ceci :

mvn eclipse:clean

mvn eclipse:eclipse

Cela a bien fonctionné pour moi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X