我开发了一个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。()
我该怎么注射它?
答案 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名称连接