尝试注入泛型类时未找到依赖项

时间:2012-09-30 17:22:47

标签: java spring dependency-injection

我开发了一个GenericDAO接口,它有两个泛型类型,实体和主键的类型:

public interface GenericDAO<E, PK extends Serializable> {
    PK save(E newInstance);
    void update(E transientObject);
    //typical dao methods
}

然后我在hibernate 4中为它们提供了一个实现:

@Transactional
@Component
@Repository
public abstract class GenericDAOHibernate4<E, PK extends Serializable> implements GenericDAO<E, PK> {
    public PK save(E newInstance) {
        return (PK) factory.getCurrentSession().save(newInstance);
    }
    public E findById(PK id) {
        return (E) factory.getCurrentSession().get(getEntityClass(), id);
    }
//method implementations
}

然后我只需要创建扩展这个抽象类的具体类:

@Component
@Transactional
@Repository
@Qualifier("userDAO")
public class UserDAO extends GenericDAOHibernate4<User, Long> {

    @Autowired
    public UserDAO(SessionFactory factory) {
        super(factory);
    }

    @Override
    protected Class<User> getEntityClass() {
        return User.class;
    }

}

然后我在需要时以这种方式注入具体的DAO:

public class UserService extends GenericService<User> {
    @Autowired
    public UserService(@Qualifier("userDAO") GenericDAO<User, Long> dao) {
        super(dao);
    }

但是,如果我需要向具体dao添加另一个方法,并因此注入具体类,spring无法找到依赖项。这在启动时失败:

public class UserService extends GenericService<User> {
    @Autowired
    public UserService(@Qualifier("userDAO") UserDAO dao) {
        super(dao);
    }

出现此错误:

  

无法实例化bean类[ddol.rtdb.services.UserService]:找不到默认构造函数;嵌套异常是java.lang.NoSuchMethodException:ddol.rtdb.services.UserService。()

我该怎么注射它?

2 个答案:

答案 0 :(得分:3)

如果一个类实现了一个接口,那么该类的bean只能使用接口类型而不是具体的类类型进行自动装配。由于UserDao实现了GenericDAO<User, Long>接口,因此当您使用该接口进行自动装配时,它正在自动装配。当您尝试使用具体类进行自动装配时,Spring无法找到依赖关系,然后它会为UserService查找无参数构造函数,并且在找不到任何特定错误时失败。

一般来说,使用具体类注入依赖项并不是一个好主意,因为它会紧密耦合模块。正确的方法是为每个DAO类创建一个接口,并使其实现扩展GenericDAOHibernate4

public interface GenericDAO<E, PK extends Serializable> {
    PK save(E newInstance);
    void update(E transientObject);
    //typical dao methods
}

public interface UserDAO extends GenericDAO<User, Long> {
    List<User> findUsersByFirstname(String firstName);
}

@Component
@Transactional
@Repository
@Qualifier("userDAO")
public class UserDAOImpl extends GenericDAOHibernate4<User, Long> 
        implements UserDAO {

    @Autowired
    public UserDAO(SessionFactory factory) {
        super(factory);
    }

    @Override
    protected Class<User> getEntityClass() {
        return User.class;
    }

    List<User> findUsersByFirstname(String firstName) {
        //provide implementation here
    }

}

public class UserService extends GenericService<User> {
    @Autowired
    public UserService(@Qualifier("userDAO") UserDAO dao) {
        super(dao);
    }
}

答案 1 :(得分:0)

@Autowired =按类型连线 @Resource =通过bean名称连接