Uploaded image for project: 'Wicket'
  1. Wicket
  2. WICKET-5808

SpringBean, support generic beans

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Resolved
    • Minor
    • Resolution: Implemented
    • 6.18.0, 7.0.0-M4
    • 7.0.0-M5
    • wicket-spring
    • 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

        1. myproject.zip
          13 kB
          Flying Wolf
        2. AnnotProxyFieldValueFactory.java
          10 kB
          Tobias Soloschenko
        3. SpringBeanLocator.java
          8 kB
          Tobias Soloschenko
        4. AnnotProxyFieldValueFactory.new.java
          10 kB
          Tobias Soloschenko
        5. SpringBeanLocator.new.java
          9 kB
          Tobias Soloschenko
        6. CollectionResolving.java
          2 kB
          Tobias Soloschenko

        Issue Links

          Activity

            People

              bitstorm Andrea Del Bene
              flyingwolf Flying Wolf
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: