在JavaEE Web服务中使用单个MongoClient

时间:2014-09-28 12:44:19

标签: mongodb java-ee singleton mongo-java

在阅读了mongo文档后,说明MongoClient的每个实例都处理自己的池,我怎样才能在整个应用程序中只有一个实例?

这似乎可能是使用单例bean的场景,但这似乎会破坏连接池的目的。如果一次只有一个用户能够访问包含MongoClient实例的bean,那么池中的多个连接肯定不会同时使用。

我对单身人士的理解是否错误,或者这确实是正确的解决方法吗?

2 个答案:

答案 0 :(得分:9)

  

但这似乎会破坏连接池的目的。如果只有一个用户能够访问那个bean   一次包含MongoClient实例,肯定是多个   池中的连接永远不会同时使用。

javadoc说:

  

Java MongoDB驱动程序是线程安全的。如果您在网络中使用   例如,服务环境应该创建一个   MongoClient实例,您可以在每个请求中使用它。的的   MongoClient对象维护一个内部连接池   数据库(默认最大池大小为100)。对于每一个请求   DB(查找,插入等)Java线程将从中获取连接   池,执行操作,并释放连接。这   表示每次使用的连接(套接字)可能不同。

因此,当您在其中创建包含客户端的单例时。它可以像Javadoc中提到的那样重复使用。不需要同步,因为它是线程安全的。

  

我如何在整个应用程序中只有一个实例?

其中一个实现可能是:

public enum ConnectionFactory {
    CONNECTION;
    private MongoClient client = null;

    private ConnectionFactory() {
        try {
            client = new MongoClient();
        } catch (Exception e) {
            // Log it.
        }
    }

    public MongoClient getClient() {
        if (client == null)
            throw new RuntimeException();
        return client;
    }
}

并在整个应用程序中使用客户端。 <{1}}将由记录的Connection pooling处理。

MongoClient

或使用@singleton注释:

MongoClient client = ConnectionFactory.CONNECTION.getClient();

参考:http://tomee.apache.org/singleton-example.html

答案 1 :(得分:3)

由于您处于java ee环境中,实现此目的的最佳方式是使用CDI生产者:

@Stateless
public class ConnetionFactory {

  @ApplicationScoped
  @Produces
  public MongoClient mongoClient() {
    return new MongoClient();
  }
}

然后在每个bean中使用它:

@Stateless
public class MyServiceBean {

  @Inject
  private MongoClient mongoClient;
}