Announcement Announcement Module
Collapse
No announcement yet.
Spring @Autowire & Interface problem Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring @Autowire & Interface problem

    Hi everybody,

    I'm facing a problem with autowired beans. I have this kind of a DAO interface:
    Code:
    public interface DaoContainer<E extends DomainObject> {
    
    	public void setType(Class<E> type);
    
    	public Class<E> getType();
    
    	public Integer addEntityItem(E entity);
    
    	public int numberOfItems();
    
    }
    and of course implemenation for the interface as well.

    I then have a class where this DAO is used like this:
    Code:
    @Configurable
    public class HelloWorld {
    
    	@Autowired
    	private DaoContainer<Notification> notificationContainer;
    
    	@Autowired
    	private DaoContainer<User> userContainer;
    
    ...
    
    }
    Notification and User are extended from DomainObject.

    I've configured DAO transactions using <tx:annotation-driven />

    Containers are autowired, but the problem is that both notificationContainer and userContainer contain the same container, namely notificationContainer.
    So if I call userContainer.numberOfItems(); I get the number of notificationContainer items.

    I've learned that I should be able to use strong typed interfaces, i.e.
    Code:
    public interface NotificationContainer extends DaoContainer<Notification> { }
    
    public interface UserContainer extends DaoContainer<User> { }
    I then should be able to use autowired containers in following manner:
    Code:
    @Configurable
    public class HelloWorld {
    
    	@Autowired
    	private NotificationContainer notificationContainer;
    
    	@Autowired
    	private UserContainer userContainer;
    
    ...
    
    }
    However, this fails to BeanCreationException:
    Code:
    org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.organization.sample.dao.NotificationContainer com.organization.sample.HelloWorld.notificationContainer; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.organization.sample.NotificationContainer] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    Using several DAOs from my controller would be very useful for my application, but I'm wondering if this is possible. I know that the problem has something to do with proxies, but I'm unable to solve it.

    Any help will be greatly appreciated!

    Cheers,
    Peders

  • #2
    You also have an implementation of your strong typed interface and have this defined (or scanned) in the application context?

    Comment


    • #3
      Hi Peders,

      Spring resolves type arguments only for collections and arrays at the moment. Another limitation is that it looks at one level only. I created enhanced generics autowiring patch and offered it Spring (SPR-6485), however, it is expected to be included to 3.1 only.

      It's possible to use the functionality now via custom autowiring configuration approach. Details are described here - Advanced autowiring filtered by generic type

      Comment


      • #4
        Hello Marten,

        My application context looks like this:
        Code:
        <context:spring-configured />
        
        <context:component-scan base-package="com.organization.sample">
            <context:exclude-filter expression="org.springframework.stereotype.Controller" 		type="annotation" />
        </context:component-scan>
        
        <tx:annotation-driven />
        I didn't have implementation for strong typed interfaces since, in my opinion, it would undermine the whole idea of a generic dao implementation. (I'd have to create the interface and implementation for every domain class which doesn't feel right). The so called "marker" interfaces I showed earlier I could live with.

        However, I tried to create implementation classes of the interfaces and ended up with this kind of classes:

        Code:
        @Repository
        public class UserContainerImpl extends DaoContainerImpl<User> implements
        		UserContainer {
        
        	private static final long serialVersionUID = 1L;
        
        
        }
        
        @Repository
        public class NotificationContainerImpl extends
        		DaoContainerImpl<Notification> implements NotificationContainer {
        
        	private static final long serialVersionUID = 1L;
        
        }
        This actually worked and this time Spring injected the correct dependencies. Still, this is far from ideal solution - I could have, say, 30 domain classes and they would all require their own interface and implementation classes.
        Last edited by peders; May 18th, 2010, 01:09 AM.

        Comment


        • #5
          Hi Denis,

          I'll take a look at the link you posted and maybe I'll take advantage of this advanced autofiltering.

          At the moment the best workaround I've found is just to simply declare my generic dao classes using xml, e.g.
          Code:
          <bean class="com.organization.sample.dao.DaoContainerImpl" id="userContainer">
              <property name="type" value="com.organization.sample.domain.User" />
          </bean>
          I'm not sure if there are drawbacks but at the moment it seems to work quite nicely. Obviously I have to do some extra xml configuring, but I guess it could be much worse.

          Comment

          Working...
          X