注入 Guice 的 DAO 应该是单例吗?

Posted

技术标签:

【中文标题】注入 Guice 的 DAO 应该是单例吗?【英文标题】:Should Guice-Injected DAO's be Singletons? 【发布时间】:2012-03-21 09:55:42 【问题描述】:

我目前正在开发一个利用 Guice / JPA / Hibernate 从我的数据库中获取信息的应用程序。

我在这里阅读了有关使用 JPA 和 EntityManagars 的 Guice 文档:http://code.google.com/p/google-guice/wiki/JPA,

但我无法理解何时应该将我的 DAO 实现设为单例。

我已经在 S/O 上阅读了这个 question 关于 Spring 对 DAO 的使用它说:

为每个请求实例化一个 DAO 会很疯狂。

这是否适用于 Spring 以外的 DI 容器?如果我将 DAO Provider 注入到我的 Servlet 并在需要时调用,那么 DAO 服务实现应该是单例吗?

这是我的一个 DAO 的基本大纲:

public DAOImpl implements DAOService  <-- SHOULD THIS BE ANNOTATED @Singleton?

    @Inject
    private EntityManager em;
    // OR 
    // @Inject 
    // private Provider<EntityManager> emProvider - If it's a singleton.

    @Inject
    DAOImpl(OtherServices os) 
        this.otherServices = os;
    

    @Transactional
    public MyPersistedObject getPersistedObject(long id) 
        MyPersistedObject mpo = em.find(MyPersistedObject.class, id);
        return mpo;
    

以及它的名称:

   @Singleton
   public MyServlet(HttpRequest req, HttpRequest res) 
           extends ServletInterfaceOfTheDay 

       private final daoService; // If Singleton
       // OR
       // private final Provider<DAOService>; If Instanced DAO

       @Inject
       MyServlet(DAOService dao) 
           this.daoService = dao;
       

       // Gather Information from request here...

       MyPersistedObject mpo = daoService.getPersistedObject(requestIdInfo);
       // OR daoService.get().getPersistedObject(requestIdInfo);

       // Process Response Info here....

   

感谢您的帮助。

【问题讨论】:

【参考方案1】:

不,因为 EntityManager 绝对不是线程安全的。您需要使用提供程序。

【讨论】:

那么通过提供者到servlet使用实例化DAOImpl?这是矫枉过正吗?我的模式错了吗? 不,我觉得很好。只需使用提供程序,您就可以开始了。我想您正在使用 PersistFilter 和 JpaPersistModule,对吧(我不完全确定名称的准确性)?或者,您可以选择在您的 DAO 中使用 Provider,这也可以正常工作。你可以单例你的 DAO JpaPersistModule 是,但没有 PersistFilter,我编辑了我的问题以包括我对 @Transactional 的使用。【参考方案2】:

是的,DAO 应该是 Singletons,但 EntityManager 必须通过提供程序检索。

【讨论】:

以上是关于注入 Guice 的 DAO 应该是单例吗?的主要内容,如果未能解决你的问题,请参考以下文章

静态类是单例吗? [复制]

moment.js 是单例吗?

阿里短信接口 client 是单例吗

我应该使用单例吗?

PHP:MVC 中的模型应该实现为单例吗? [复制]

我应该为我的视图控制器使用单例吗?