Java 如何使用泛型在抽象类中注入服务

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 }

我试图创建一个通用的抽象服务类,通过将服务层对象(DTO?)、数据层实体及其对应的DAO组合在一起,为我的服务层提供公共crud操作

DAO层是标准的问题抽象,其中我的DAO扩展了一个抽象JPAIMPL:

@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功能的添加,服务层上似乎有重复的工作。他希望把这部作品抽象出来,而不是复制和粘贴。帮助清理代码并简化将来的添加。