【问题标题】:CDI GenericDAO and custom implementationsCDI GenericDAO 和自定义实现
【发布时间】:2015-03-13 10:24:11
【问题描述】:

我在这里需要大脑! :p

我有一个接口IDAO,T是实体类,K是主键类。

我开发了一个具体的类 GenericDAO,它提供 CRUD 操作和具有自动获取的条件查询(我创建了一个方面 @Joinfetch 我在实体关系上使用)。如果你愿意,我可以显示代码,但这不是主题:)。

这里是生产 GenericDAO 的工厂:

public class GenericDAOProducer {

@PersistenceContext
EntityManager em;

@Produces
@Default
public <T, K> IDAO<T, K> producesGenericDAO(
        final InjectionPoint injectionPoint) {
    final ParameterizedType type = (ParameterizedType) injectionPoint
            .getType();
    // Because of the new, i got to inject the class and the entity manager
    // manualy
    final IDAO<T,K> dao = new GenericDAO<T, K>(this.em,
            (Class) type.getActualTypeArguments()[0]);
    dao.init(); //cool stuff here to prepare some criteria queries
    return dao;
}
}

有时我需要 DAO 的其他实现(例如复杂的获取)。这些实现也通过 IDAO 外观公开了它们的方法。我希望以与 GenericDAO 相同的方式注入这些 DAO。

这是我想要的示例功能:

我需要在某处注入 IDAO 的实现。 如果存在一个类实现 IDAO 那么我希望 CDI 选择这个实现。 否则,如果 IDAO 没有实现,我希望 CDI 选择工厂生产的 GenericDAO。

我很难用英语解释。希望你能理解我的问题。

您有最佳做法吗?

谢谢!

【问题讨论】:

  • 我创造了一些非常酷的东西来做到这一点!我会尽快分享:)
  • 您可能想查看DeltaSpike Data,了解基于 CDI 的通用 DAO。
  • 这是一个非常有趣的 API,谢谢!但我认为它根本不会创建没有类的强类型 DAO。您需要按实体声明至少一个@Repository。问题是我的应用程序存储了大量数据,每个月我都需要添加一个实体类及其关系。然后我必须编写每个级别的类。使用我的模式,如果我想覆盖或添加一些方法,我根本不需要编写 DAO。

标签: java jakarta-ee jpa cdi


【解决方案1】:

我需要两个@Qualifier

@Qualifier
@Retention(RUNTIME)
@Target({ METHOD, FIELD, PARAMETER, TYPE })
public @interface Generic {}


@Qualifier
@Retention(RUNTIME)
@Target({ METHOD, FIELD, PARAMETER, TYPE })
public @interface Specific {
Class<?> classe();
}

IDAO 接口

public interface IDAO<T, PK> extends Serializable {

public abstract T create(T entity) throws DAOException;

public abstract T edit(T entity) throws DAOException;

public abstract void remove(T entity) throws DAOException;

public abstract T find(PK id) throws DAOException;

public abstract T findWithFetch(PK id) throws DAOException;

public abstract List<T> findAll();

public abstract T getRef(PK id);
}

IDefaultDAO

public interface IDefaultDAO<T, PK> extends IDAO<T, PK> {
public void setEntityClass(final Class<T> entityClass);
}

抽象 DAO

public abstract class AbstractDAO<T, PK> implements IDAO<T, PK> {

@PersistenceContext
protected EntityManager em;

@Inject
protected transient Logger logger;

protected Class<T> entityClass;

protected final Class<T> getEntityClass() {
    if (this.entityClass == null) {
        this.entityClass = ((Class) ((ParameterizedType) this.getClass()
                .getGenericSuperclass()).getActualTypeArguments()[0]);

    }
    return this.entityClass;
}

//methods implementations
}

默认 DAO

@Generic
public class DefaultDAO<T, PK> extends AbstractDAO<T, PK> implements
    IDefaultDAO<T, PK> {

@Override
public void setEntityClass(final Class<T> entityClass) {
    this.entityClass = entityClass;
}
}

一个特定的 DAO

@Specific(classe=Delegation.class)
public class DelegationDAO extends AbstractDAO<Delegation, Integer>
implements IDAO<Delegation, Integer> {
// do things differently
}

DAO 生产者

public class GenericDAOProducer {

@Inject
private transient Logger logger;

@Produces
public <T, PK> IDAO<T, PK> producesDAO(final InjectionPoint injectionPoint,
        @Generic final IDefaultDAO<T, PK> genericDAO,
        @Any Instance<IDAO<T, PK>> specDAOInstance) {

    // JPA Class (T)
    final ParameterizedType type = (ParameterizedType) injectionPoint
            .getType();
    final Class<T> entityClass = (Class) type.getActualTypeArguments()[0];

    this.logger.info("Search DAO " + entityClass);

    // Search specific DAO

    specDAOInstance = specDAOInstance.select(new SpecificLiteral(
            entityClass));

    if ((specDAOInstance != null) && !specDAOInstance.isAmbiguous()
            && !specDAOInstance.isUnsatisfied()) {
        this.logger.info("Implementation found! ");
        return specDAOInstance.get();
    } else {

        this.logger
                .info("Implementation not found! Return generic DAO."
                        + entityClass);

        genericDAO.setEntityClass(entityClass);
        return genericDAO;
    }
  }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-18
    • 1970-01-01
    • 2014-12-13
    • 2011-02-21
    • 1970-01-01
    • 2011-04-17
    相关资源
    最近更新 更多