Spring 3.2 Autowire generic types

Stephen Lujan picture Stephen Lujan · Jan 16, 2013 · Viewed 13.8k times · Source

So I have a number of generics in Spring 3.2 and ideally my architecture would look something like this.

class GenericDao<T>{}

class GenericService<T, T_DAO extends GenericDao<T>>
{
    // FAILS
    @Autowired
    T_DAO;
}

@Component
class Foo{}

@Repository
class FooDao extends GenericDao<Foo>{}

@Service
FooService extends GenericService<Foo, FooDao>{}

Unfortunately with multiple implementations of the generics the autowiring throws an error about multiple matching bean definitions. I assume this is because @Autowired processes before type erasure. Every solution I've found or come up with looks ugly to me or just inexplicably refuses to work. What is the best way around this problem?

Answer

matsev picture matsev · Mar 30, 2013

How about adding a constructor to the GenericService and move the autowiring to the extending class, e.g.

class GenericService<T, T_DAO extends GenericDao<T>> {
    private final T_DAO tDao;

    GenericService(T_DAO tDao) {
        this.tDao = tDao;
    }
}

@Service
FooService extends GenericService<Foo, FooDao> {

    @Autowired
    FooService(FooDao fooDao) {
        super(fooDao);
    }
}

Update:

As of Spring 4.0 RC1, it is possible to autowire based on generic type, which means that you can write a generic service like

class GenericService<T, T_DAO extends GenericDao<T>> {

    @Autowired
    private T_DAO tDao;
}

and create multiple different Spring beans of it like:

@Service
class FooService extends GenericService<Foo, FooDao> {
}