0

我开发了一个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.()

我应该如何注入它?

4

2 回答 2

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);
    }
}
于 2012-09-30T18:26:45.303 回答
0

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

于 2012-09-30T18:46:28.770 回答