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

时间:2011-05-14 23:13:24

标签: java spring design-patterns generics abstraction

我正在尝试创建一个通用的抽象服务类,它通过将服务层对象(DTO?),数据层实体及其相应的DAO集合在一起,为我的服务层提供常见的crud操作。

DAO层是标准问题抽象,我的DAO扩展了AbstractJpaImpl:

@Repository
public abstract class AbstractJpaBaseDaoImpl<K extends Serializable, E> implements BaseDao<K, E> {
//Dao implementation
}

DAO扩展了这个类并实现了它们各自的扩展BaseDao的dao接口。

我希望在我的服务层创建类似的东西,但是我如何注入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 ...
}

使用泛型在这个摘要中注入服务的最简洁方法是什么?

D扩展AbstractJpaBaseDaoImpl 不切割它。我可以遵循一种模式吗?

2 个答案:

答案 0 :(得分:0)

您可以尝试使用@PostConstruct注释方法将基本抽象类中的变量与实例化的bean连接起来。这些抽象类可以接受基本的CRUd操作实现。示例代码如下。我希望我能以某种方式帮助你查询。

@PostConstruct public void setupService() {
    baseDao = userDao;
}

答案 1 :(得分:0)

其他一些类型的定义是什么?如AbstractBaseCrudBean,BaseCrudService等?有很多编译错误很难归结为你的根本问题。

然而,简单泛型声明没有削减它的原因是没有实例可以调用D的方法。你需要这样的东西:

private final D dao;

然后使用@Inject @Named来装饰它(因为在擦除之后你可能会有很多相同类型的DAO)。因此,DAO的每个实现都需要具有唯一的字符串名称,这可能是也可能不是什么大问题。