我正在尝试遵循代码重用最佳实践。 我有通用的 DAO 接口(interface)和一些常用方法:
public interface DaoInterface<T> {
T findById(int id);
//...more methods...
}
及其实现类:
public class GenericDao<T> implements DaoInterface<T> {
@SuppressWarnings("unchecked")
private final Class<T> persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
@Autowired
protected SessionFactory sessionFactory;
@Override
@SuppressWarnings("unchecked")
public T findById(int id) {
Session session = sessionFactory.getCurrentSession();
return (T) session.get(persistentClass, id);
}
//...more methods...
}
然后我的每个具体实现类都扩展 GenericDao
并实现其接口(interface)。
我的应用程序中也有服务层。某些服务的方法将其工作完全委托(delegate)给 DAO 类。因此,在每个具体的 Service 实现中,我 Autowiring 适当的 DAO 类并调用其方法。 所以现在看起来:
public interface CustomerService {
Customer findById(int id);
}
和实现:
@Service
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class CustomerServiceImpl implements CustomerService {
@Autowired
private CustomerDao customerDao;
@Override
public Customer findById(int id) {
return customerDao.findById(id);
}
}
我的问题是 - 如何以与 DAO 相同的方式生成 Service 类?这样我的具体类就会看起来:
public class CustomerServiceImpl extends GenericService<Customer> implements CustomerService {
.....
}
问题是我无法在通用服务中 Autowiring DAO 类:
@Autowired
private GenericDao<T> dao;
这样我就可以调用dao
的方法。
我应该在构造函数中执行它吗?
还有一个问题 - 在泛型类或每个实现类中使用 @Transactional
注释方法的正确位置在哪里?
最佳答案
您必须创建一个通用 Dao 的实例,并在服务层中放入一些决策:
@Repository
public class GenericDao implements DaoInterface<T> {
//The type must be aquired at runtime,otherwise it may not be thread safe
@Autowired
protected SessionFactory sessionFactory;
@Override
@SuppressWarnings("unchecked")
public T findById(int id,Class<?> persistenceClass) {
Session session = sessionFactory.getCurrentSession();
return (T) session.get(persistenceClass, id);
}
//...more methods...
}
此外,如果您需要一个好的通用存储库层,请查看 Spring Data Jpa
这将生成 GenericDao 的唯一一个实例。
接下来你有两个选择:
- 创建满足您所有需求的单例服务
为每个实体创建一个类服务
abstract class GenericService<T> { @Autowired protected GenericDao dao; @SuppressWarnings("unchecked") protected final Class<T> persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]; @Override public T findById(int id) { return dao.findById(id,persistenceClass); } }
现在,您的每一项服务都必须使用提供的持久性类型扩展 GenericService,工作就完成了。
关于java - 生成服务层类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37765960/