[
https://issues.apache.org/jira/browse/WICKET-5808?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14269282#comment-14269282
]
Flying Wolf commented on WICKET-5808:
-------------------------------------
But wouldn't it be an improvement if SpringBean is able to support generics
like Spring 4? At the moment, SpringBean ignores generics causing it to find
multiple bean candidates, which is causing the problem. While Spring 4 does
support generics and is able to narrow down to one bean candidate.
> SpringBean, support generic beans
> ---------------------------------
>
> Key: WICKET-5808
> URL: https://issues.apache.org/jira/browse/WICKET-5808
> Project: Wicket
> Issue Type: Improvement
> Components: wicket-spring
> Affects Versions: 6.18.0
> Environment: Spring Framework 4.1.4.RELEASE (currently the latest
> version)
> Reporter: Flying Wolf
> Priority: Minor
> Labels: generics, spring
> Attachments: myproject.zip
>
>
> *Short Description:*
> Since Spring Framework 4.0, Spring is able to inject/autowire generic beans
> like:
> {code}@Autowired public GenericDao<Car> genericCarDao;{code}
> 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:
> {code}public interface GenericDao<T> {}{code}
> {code}@Repository
> public class CarDao implements GenericDao<Car> {}{code}
> {code}@Repository
> public class PhoneDao implements GenericDao<Phone> {}{code}
> {code}@Component
> public class DaoClient {
> @Autowired public GenericDao<Car> genericCarDao;
> @Autowired public CarDao nonGenericCarDao;
> }{code}
> Spring 4 is able to inject both "genericCaoDao" and "nonGenericCarDao" into
> the DaoClient class.
> Performing the same using SpringBean, fails:
> {code}public class HomePage extends WebPage {
> @SpringBean private CarDao nonGenericCarDao;
> @SpringBean private GenericDao<Car> genericCarDao;
> //.....
> }
> {code}
> In this case, SpringBean is unable to inject "genericCarDao", and throws the
> following error:
> {code}
> 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)
> {code}
> *Workaround solution:*
> Explicitly using bean names (qualifiers) does work. In this case
> {code}
> @SpringBean private CarDao nonGenericCarDao;
> @SpringBean private GenericDao<Car> genericCarDao;
> {code}
> has to be changed to:
> {code}
> @SpringBean(name = "carDao") private CarDao nonGenericCarDao;
> @SpringBean(name = "carDao") private GenericDao<Car> genericCarDao;
> {code}
> *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.
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)