2012-12-10 9 views
31

Mam problem z niektórymi definicjami komponentu bean. Mam kilka kontekstowych plików xml, które są ładowane przez moją metodę main(), a obie zawierają prawie wyłącznie znacznik. Kiedy zaczyna się mój główny sposób, otrzymuję ten błąd od wiosny:Konflikty nazw określone przez adnotację są w konflikcie z istniejącym, niekompatybilnym defektem ziarnowym.

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] 

Obie klasy DAO są opisywane w ten sposób:

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

in-memory dao ma również @Repository ("converterDAO") adnotacja. DAO jest wymieniony w innych klasach tak:

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

chcę jeden DAO zastąpić definicję drugiego, który jak zawsze rozumiany był to jeden z głównych powodów, aby używać ramy DI w pierwszym miejsce. Robiłem to z definicjami XML przez lata i nigdy nie miałem żadnych problemów. Ale nie w przypadku skanów komponentów i definicji z przypisanymi fasolami? A co oznacza Spring, kiedy mówi, że nie są "kompatybilne"? Implementują ten sam interfejs i są autowyredowane na pola o tym typie interfejsu. Dlaczego do cholery oni nie są zgodni?

Czy ktoś może zapewnić mi sposób na jedną przesłoniętą adnotację, komponentową fasolkę, aby zastąpić inną?

-Mike

+0

jest coś śmiesznego z tobą drugi fragment kodu ... proszę sprawdź to. – Yevgeniy

+0

Może musisz udostępnić swoją główną metodę? –

+0

Proszę dodać rzeczywistą deklarację pola converterDAO. Czy jest to interfejs lub implementacja 'ConverterDao' - nie wynika to z pytania. –

Odpowiedz

22

w pliku XML, jest sekwencja zgłoszeń i może zastąpić poprzednią definicję z nowszej. Podczas korzystania z adnotacji nie ma żadnego pojęcia o wartości przed lub po. Wszystkie ziarna są na tym samym poziomie. Zdefiniowałeś dwie fasole o tej samej nazwie, a Spring nie wie, którą z nich wybrać.

Daj im inną nazwę (staticConverterDAO, inMemoryConverterDAO na przykład), należy utworzyć alias w pliku Wiosna XML (theConverterDAO na przykład), i użyć tego aliasu podczas wstrzykiwania konwerter:

@Autowired @Qualifier("theConverterDAO") 
+1

Dlaczego nie ma pojęcia przed lub po? Mam dwa pliki kontekstowe, jeden jest załadowany, a następnie następny. Pod tym względem nie różni się to od definicji czystych XML. Kolejność jest po prostu kolejnością, w której napotkano instrukcje skanowania komponentu. Ziarna wytwarzane podczas drugiego skanu zastępują ziarna wytworzone podczas pierwszego skanu. Słyszę, co mówisz, ale nie rozumiem logiki i przyczyn technicznych. Również nie jest to udokumentowane, a wyjątek nie ma żadnego sensu. Nie twoja wina oczywiście :-) Punkty za pomysł na alias. Lepsze niż powrót do definicji xml. – user1283068

+0

Co więcej, w odniesieniu do sugestii , wynika z tego, że wszystkie różne implementacje ConverterDAO będą wykrywane i tworzone przez Spring, kiedy załadowane zostaną pliki kontekstowe. W przypadku XML zostanie wdrożona tylko ostatnia nadrzędna implementacja. Oznacza to, że muszą istnieć wszystkie autoczydowane zależności wszystkich implementacji ConverterDAO, nawet jeśli tylko jeden zostanie kiedykolwiek użyty. – user1283068

+0

Każda strategia, aby uniknąć konfliktu nazwy fasoli z archiwami jar? – Stephane

19

Miałem podobny problem, z dwoma bibliotekami jar (app1 i app2) w jednym projekcie. Ziarno "BeanName" jest zdefiniowane w app1 i jest rozszerzone w app2, a komponent bean został ponownie zdefiniowany o tej samej nazwie.

W APP1:

package com.foo.app1.pkg1; 

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

W App2:

package com.foo.app2.pkg2; 

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

Powoduje to wyjątek w załadunku ApplicationContext ConflictingBeanDefinitionException z tego samego Nazwa składnika ziarna.

Aby rozwiązać ten problem, na wiosnę plik konfiguracyjny 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> 

Więc Klasa1 jest wykluczone, aby być automatycznie skanowane i komponent przyporządkowany do fasoli, unikając konfliktu nazw.

12

Miałem podobny problem z wiosną 4.x przy użyciu @RestController.Dwa różne pakiety miał klasę o tej samej nazwie ...

package com.x.catalog 

@RestController 
public class TextureController { 
... 

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

Rozwiązaniem było łatwe ...

package com.x.catalog 

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

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

Problem wydaje się być to, że adnotacja zostanie autowired i trwa przez nazwę klasy domyślna. Nadanie jej wyraźnej nazwy w adnotacji @RestController pozwala zachować nazwy klas.

+1

Dzięki, pracował jak urok. – Azim

Powiązane problemy