Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 注射DAO和x27的最佳实践;s_Java_Jpa_Cdi_Dao - Fatal编程技术网

Java 注射DAO和x27的最佳实践;s

Java 注射DAO和x27的最佳实践;s,java,jpa,cdi,dao,Java,Jpa,Cdi,Dao,我正在支付我的费用,我面临的一个问题是在CDI注射中使用DAO 我确实写了一篇关于(当然是使用CDI)的博客,它的效果非常好,我将使用博客的参考资料来回答我的问题。我现在的情况是,我有这么多数据库表(当然是标准化的),为每个表创建DAO并不是问题所在。问题是当一个服务(假设和EJB会话Bean)具有对许多DAO的“引用”时,如下面的示例所示: @Stateless public class CustomerServiceEJB implements CustomerServiceLocal, C

我正在支付我的费用,我面临的一个问题是在CDI注射中使用DAO

我确实写了一篇关于(当然是使用CDI)的博客,它的效果非常好,我将使用博客的参考资料来回答我的问题。我现在的情况是,我有这么多数据库表(当然是标准化的),为每个表创建DAO并不是问题所在。问题是当一个服务(假设和EJB会话Bean)具有对许多DAO的“引用”时,如下面的示例所示:

@Stateless
public class CustomerServiceEJB implements CustomerServiceLocal, CustomerServiceRemote, CustomerService {

 private static final Logger LOGGER = Logger.getLogger(CustomerServiceEJB.class.getName());

 @Inject @JPADAO
 private CustomerDAO customerDAO; 

 @Inject @JPADAO
 private CustomerAccountDAO customerAccountDAO;

 @Inject @JPADAO
 private CustumerCredentialDAO customerCredentialDAO;

 //And rougly 15 more DAO's.
}
如您所见,如果我们需要使用各种DAO,则该类具有所有DAO的“实例”,这意味着CDI容器必须在使用之前注入所有DAO

我提出的一个解决方案是创建一个
DAOManager
,其中DAO的所有引用都列在管理器中

例如:

public interface DAOManager {

    public CustomerDAO getCustomerDAO(); 

    public CustomerAccountDAO getCustomerAccountDAO();

    public CustumerCredentialDAO getCustomerCredentialDAO();

    //Etc
}
这是JPA的代表:

@JPADAO
public class JPADAOManager implements DAOManager {

    @PersistenceContext
    private EntityManager entityManager;

    public CustomerDAO getCustomerDAO() {
        return new JPACustomerDAO(entityManager);
    }

    //Etc...
}
最后,在
CustomerServiceEJB
中,我可以按如下方式注入DAO:

@Inject @JPADAO
private DAOManager daoManager;

我的问题:我的方法正确吗?如果不是,最好的方法是什么?另外,在将DAO与CDI一起使用时,我需要考虑什么?添加的问题:是否应
JPADAOManager
以延迟加载方式返回DAO?

如您所见,如果我们需要使用各种DAO,则该类具有所有DAO的“实例”,这意味着CDI容器必须在使用之前注入所有DAO。这是个什么问题?CDI为您提供了依赖项注入,它极大地帮助您测试代码,避免编写无用的工厂,并识别您的依赖项。DAO是服务的依赖项。让它保持原样。很好。如果一个服务有太多的DAO依赖项,这只是一个信号,表明您的服务有太多的责任,应该加以反思。@JB Nizet这些是不能忽略的责任类型。典型的例子是用户身份验证:需要提取密码salt并验证输入的密码是否与数据库中存储的哈希密码匹配。另外,维护所有登录尝试和无效密码的日志,以及设置用户状态(登录、注销)等。现在,将所有这些封装在
DAOManager
中意味着服务层上的代码更干净,而不是服务上有许多DAO。这是重构过程的一部分,但需要添加一个附加层。它是好的还是坏的?代码如何更干净?您依赖的不是定义良好且可识别的DAO集,而是一个允许访问系统中每个DAO的God对象,并被迫使用查找方法(getFooDao()、getBarDao()),而不是直接使用字段。在测试中,您必须模拟所有这些查找方法,而不是依赖于您的本地模拟框架对DI的支持(例如,在Mockito中,
@mock
@InjectMocks
)。你所看到的问题实际上是一件好事,但我不明白。在这种情况下,我将不考虑创建<代码> DaMaNanger-<代码>,并按原样执行。我将把这个问题留给那些有类似想法的人来回答。整个概念是一个OO原则的问题。更准确地说:接口隔离原则()。这样,您可能不会按表dao注入dao,但您会重新考虑所需的最小接口是什么,并将注入一个实现该简单接口的类。