Details
-
Improvement
-
Status: Resolved
-
Minor
-
Resolution: Implemented
-
6.18.0, 7.0.0-M4
-
Spring Framework 4.1.4.RELEASE (currently the latest version)
Description
Short Description:
Since Spring Framework 4.0, Spring is able to inject/autowire generic beans like:
@Autowired public GenericDao<Car> genericCarDao;
As is described here: http://spring.io/blog/2013/12/03/spring-framework-4-0-and-java-generics .
However, SpringBean doesn't seem to support this yet, resulting in a IllegalStateException.
Detailed Description
Given the following code:
public interface GenericDao<T> {}
@Repository public class CarDao implements GenericDao<Car> {}
@Repository public class PhoneDao implements GenericDao<Phone> {}
@Component public class DaoClient { @Autowired public GenericDao<Car> genericCarDao; @Autowired public CarDao nonGenericCarDao; }
Spring 4 is able to inject both "genericCaoDao" and "nonGenericCarDao" into the DaoClient class.
Performing the same using SpringBean, fails:
public class HomePage extends WebPage { @SpringBean private CarDao nonGenericCarDao; @SpringBean private GenericDao<Car> genericCarDao; //..... }
In this case, SpringBean is unable to inject "genericCarDao", and throws the following error:
Caused by: java.lang.IllegalStateException: More than one bean of type [com.mycompany.springcomponents.GenericDao] found, you have to specify the name of the bean (@SpringBean(name="foo")) or (@Named("foo") if using @javax.inject classes) in order to resolve this conflict. Matched beans: carDao,phoneDao at org.apache.wicket.spring.injection.annot.AnnotProxyFieldValueFactory.getBeanNameOfClass(AnnotProxyFieldValueFactory.java:289) at org.apache.wicket.spring.injection.annot.AnnotProxyFieldValueFactory.getBeanName(AnnotProxyFieldValueFactory.java:198) at org.apache.wicket.spring.injection.annot.AnnotProxyFieldValueFactory.getFieldValue(AnnotProxyFieldValueFactory.java:130) at org.apache.wicket.injection.Injector.inject(Injector.java:111) at org.apache.wicket.spring.injection.annot.SpringComponentInjector.inject(SpringComponentInjector.java:124) at org.apache.wicket.spring.injection.annot.SpringComponentInjector.onInstantiation(SpringComponentInjector.java:130) at org.apache.wicket.application.ComponentInstantiationListenerCollection$1.notify(ComponentInstantiationListenerCollection.java:38) at org.apache.wicket.application.ComponentInstantiationListenerCollection$1.notify(ComponentInstantiationListenerCollection.java:34) at org.apache.wicket.util.listener.ListenerCollection.notify(ListenerCollection.java:80) at org.apache.wicket.application.ComponentInstantiationListenerCollection.onInstantiation(ComponentInstantiationListenerCollection.java:33) at org.apache.wicket.Component.<init>(Component.java:687) at org.apache.wicket.MarkupContainer.<init>(MarkupContainer.java:121) at org.apache.wicket.Page.<init>(Page.java:168) at org.apache.wicket.Page.<init>(Page.java:157) at org.apache.wicket.markup.html.WebPage.<init>(WebPage.java:106) at com.mycompany.HomePage.<init>(HomePage.java:22)
Workaround solution:
Explicitly using bean names (qualifiers) does work. In this case
@SpringBean private CarDao nonGenericCarDao; @SpringBean private GenericDao<Car> genericCarDao;
has to be changed to:
@SpringBean(name = "carDao") private CarDao nonGenericCarDao; @SpringBean(name = "carDao") private GenericDao<Car> genericCarDao;
Description of some of the attached files:
- pom.xml: added spring-context, spring-web, wicket-spring dependencies. Changed java version to 1.8.
- WicketApplication: added Spring support
- SpringApp: boots plain Spring and shows that DaoClient is able to autowire generic beans.
- HomePage: a Wicket WebPage that shows that SpringBean throws the error when using generic beans.
Attachments
Attachments
Issue Links
- links to