[英]Generifying Service layer classes
I'm trying to follow code reusing best practices. 我正在尝试遵循代码重用最佳实践。 I have generic DAO interface with some common methods: 我有一些常用方法的通用DAO接口:
public interface DaoInterface<T> {
T findById(int id);
//...more methods...
}
and its implementation class: 及其实现类:
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...
}
Then my every concrete implementation class extends GenericDao
and implements its interface. 然后,我的每个具体实现类都扩展GenericDao
并实现其接口。
I also have Service layer in my application. 我的应用程序中也有Service层。 Some Services' methods completely delegate their work to DAO classes. 一些服务的方法将其工作完全委派给DAO类。 So in the each concrete Service implementation I autowire appropriate DAO class and call its methods. 因此,在每个具体的Service实现中,我都会自动装配适当的DAO类并调用其方法。 So now it looks: 所以现在看起来:
public interface CustomerService {
Customer findById(int id);
}
and implementation: 和实现:
@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);
}
}
My question is - how to generify Service classes in the same way as DAO? 我的问题是-如何以与DAO相同的方式来生成服务类? So that my concrete class will look: 这样我的具体课程将看起来像:
public class CustomerServiceImpl extends GenericService<Customer> implements CustomerService {
.....
}
The problem is that I cannot autowire DAO class in Generic Service: 问题是我无法在通用服务中自动装配DAO类:
@Autowired
private GenericDao<T> dao;
so that I could call dao
's methods. 这样我就可以调用dao
的方法了。 Should I do it in the constructor? 我应该在构造函数中执行此操作吗?
And one more question - where is the right place to annotate methods with @Transactional
- in generic class or in every implementation class? 还有一个问题-在泛型类或每个实现类中,使用@Transactional
注释方法的正确位置在哪里?
You have to create an instance of a generic Dao and put in the service layer some decision: 您必须创建一个通用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...
}
Also if you need a good generic repository layer take a look for Spring Data Jpa 另外,如果您需要良好的通用存储库层,请查看Spring Data Jpa
This will make one and only one instance of the GenericDao. 这将仅创建 GenericDao的一个实例。
Next you have 2 choice: 接下来,您有2个选择:
Create a class service for every entity 为每个实体创建类服务
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); } }
Now every one of your service must extends the GenericService with a supplied persistence type and the job is done. 现在,您的每一项服务都必须使用提供的持久性类型扩展GenericService,然后工作就完成了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.