java - 生成服务层类

标签 java spring generics service dao

我正在尝试遵循代码重用最佳实践。 我有通用的 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 的唯一一个实例。

接下来你有两个选择:

  1. 创建满足您所有需求的单例服务
  2. 为每个实体创建一个类服务

    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/

相关文章:

java - Spring - beans 生命周期

Java泛型不完全理解

java - 二维RGB数组转BufferedImage

java - 在 Spring 过滤器中更改 HttpServletRequest 的 POST 主体

java - InheritanceType.JOINED 策略不适用于 Spring Boot

c# - 参数化返回类型是否需要泛型方法签名?

java - 为什么我们不能使用扩展边界添加java泛型中的元素?

java - 使用 jwt token 身份验证识别用户

java - IntelliJ Git 集成插件 -> "New Branch"将大写 F 放入 "feature/abc"

java - 从资源目录获取文件进行单元测试,但获取产品的绝对路径