Java 如何使用泛型在抽象类中注入服务
我试图创建一个通用的抽象服务类,通过将服务层对象(DTO?)、数据层实体及其对应的DAO组合在一起,为我的服务层提供公共crud操作 DAO层是标准的问题抽象,其中我的DAO扩展了一个抽象JPAIMPL:Java 如何使用泛型在抽象类中注入服务,java,spring,design-patterns,generics,abstraction,Java,Spring,Design Patterns,Generics,Abstraction,我试图创建一个通用的抽象服务类,通过将服务层对象(DTO?)、数据层实体及其对应的DAO组合在一起,为我的服务层提供公共crud操作 DAO层是标准的问题抽象,其中我的DAO扩展了一个抽象JPAIMPL: @Repository public abstract class AbstractJpaBaseDaoImpl<K extends Serializable, E> implements BaseDao<K, E> { //Dao implementation }
@Repository
public abstract class AbstractJpaBaseDaoImpl<K extends Serializable, E> implements BaseDao<K, E> {
//Dao implementation
}
@存储库
公共抽象类AbstractJPABASEADOIMPL实现BaseDao{
//Dao实现
}
dao扩展这个类,并实现各自的dao接口来扩展BaseDao
我希望在我的服务层中创建类似的东西,但是如何注入dao本身呢
public abstract class AbstractBaseCrudServiceImpl<K extends Serializable, B extends AbstractBaseCrudBean, P, D extends AbstractJpaBaseDaoImpl<K,P>>
implements BaseCrudService<K, B> {
protected Class<B> businessObject;
protected Class<P> persistObject;
protected Class<D> dao;
@SuppressWarnings("unchecked")
public AbstractBaseCrudServiceImpl() {
//Extract the class type by accessing this classes parameters by index <0,1...> so 0 is K and 1 is E.
this.businessObject = (Class<B>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];
this.persistObject = (Class<P>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[2];
this.dao = (Class<D>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[3];
}
//stuff ...
@Transactional
@SuppressWarnings("unchecked")
@Override
public void remove(B businessObject) {
logger.debug("Remove " + getBusinessObjectCanonicalName() + " id= " + businessObject.getId());
try {
getDao().remove(businessObject.getId()); //DOES NOT RECOGNIZE REMOVE METHOD
} catch (Exception e) {
logger.error("Unable to delete " + getBusinessObjectCanonicalName() + " record id=" + businessObject.getId(), e);
}
}
//stuff ...
}
公共抽象类AbstractBaseCrudServiceImpl
实现BaseCrudService{
保护类业务对象;
保护类persistObject;
保护类dao;
@抑制警告(“未选中”)
公共抽象BaseCrudServiceImpl(){
//通过索引访问这些类参数来提取类类型,因此0是K,1是E。
this.businessObject=(Class)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[1];
this.persistObject=(Class
)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[2];
this.dao=(Class)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[3];
}
//东西。。。
@交易的
@抑制警告(“未选中”)
@凌驾
公共无效删除(B businessObject){
logger.debug(“删除”+getBusinessObjectCanonicalName()+“id=“+businessObject.getId());
试一试{
getDao().remove(businessObject.getId());//无法识别remove方法
}捕获(例外e){
logger.error(“无法删除”+getBusinessObjectCanonicalName()+“记录id=“+businessObject.getId(),e”);
}
}
//东西。。。
}
使用泛型在这个抽象中注入服务最干净的方法是什么
D扩展了抽象的JPABASEADOIMPL不要切割它。有一种模式我可以遵循吗?您可以尝试使用@PostConstruct注释的方法将基本抽象类中的变量与实际的实例化bean连接起来。这些抽象类可以包含基本的CRUd操作实现。下面提供了示例代码。我希望我在某种程度上帮助了你的提问
@PostConstruct public void setupService() {
baseDao = userDao;
}
其他一些类型的定义是什么?例如AbstractBaseCrudBean、BaseCrudService等。?有太多的编译错误,很难弄清您的根本问题是什么 但是,简单泛型声明没有将其切分的原因是没有可调用D方法的实例。您需要类似以下内容:
private final D dao;
然后用@Inject@Named装饰它(因为在擦除之后,您可能会有许多相同类型的DAO)。因此,DAO的每个实现都需要有一个唯一的字符串名,这可能是一件大事,也可能不是 是否有必要在您的服务和DAO中添加泛型?为了“类型纯度”,这感觉有点过分了。根据我的经验,这通常是一个负的ROI。随着每个crud功能的添加,服务层上似乎有重复的工作。他希望把这部作品抽象出来,而不是复制和粘贴。帮助清理代码并简化将来的添加。