【问题标题】:How to inject a service within abstract class using generics如何使用泛型在抽象类中注入服务
【发布时间】:2011-05-14 23:13:24
【问题描述】:

我正在尝试创建一个通用抽象服务类,通过将服务层对象 (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 extends AbstractJpaBaseDaoImpl 并没有削减它。有没有我可以遵循的模式?

【问题讨论】:

  • 是否有需要推动向您的服务和 DAO 添加泛型?为了“类型纯度”,这感觉有点矫枉过正。根据我的经验,这通常是负投资回报率。
  • 随着每个 crud 功能的添加,服务层似乎有重复的工作。希望抽象出这项工作,而不是复制和粘贴。帮助清理代码并简化未来的添加。

标签: java spring design-patterns generics abstraction


【解决方案1】:

您可以尝试使用 @PostConstruct 注释方法将基本抽象类中的变量与实际实例化的 bean 连接起来。这些抽象类可以包含基本的 CRUd 操作实现。下面提供的示例代码。希望对您的查询有所帮助。

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

【讨论】:

    【解决方案2】:

    其他一些类型的定义是什么?比如 AbstractBaseCrudBean、BaseCrudService 等?编译错误太多了,很难弄清楚你的根本问题是什么。

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

    private final D dao;
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-22
      • 1970-01-01
      • 2019-09-24
      • 1970-01-01
      • 1970-01-01
      • 2020-11-11
      • 1970-01-01
      • 2018-10-29
      相关资源
      最近更新 更多