- 获取mongoClient对象,通过 mongoClients.create方法
class MongoClientImpl implements MongoClient {
private static final Logger LOGGER = Loggers.getLogger("client");
private final Cluster cluster; //连接池在这个里面
private final MongoClientSettings settings; //仅连接池的配置,但连接池在哪呢?
private final AsyncOperationExecutor executor;
private final Closeable externalResourceCloser;
MongoClientImpl(final MongoClientSettings settings, final Cluster cluster, final Closeable externalResourceCloser) {
this(settings, cluster, createOperationExecutor(settings, cluster), externalResourceCloser);
}
MongoClientImpl(final MongoClientSettings settings, final Cluster cluster, final AsyncOperationExecutor executor) {
this(settings, cluster, executor, null);
}
MongoClientImpl(final MongoClientSettings settings, final Cluster cluster, final AsyncOperationExecutor executor,
final Closeable externalResourceCloser) {
this.settings = notNull("settings", settings);
this.cluster = notNull("cluster", cluster);
this.executor = notNull("executor", executor);
this.externalResourceCloser = externalResourceCloser;
}
}
MongoClientImpl的构造方法调用,其中cluster是线程池的持有者,主要分析cluster的创建过程
return new MongoClientImpl(settings, cluster, mongoDriverInformation), externalResourceCloser);
cluster = new DefaultClusterFactory().create(
settings.getClusterSettings(),
settings.getServerSettings(),
settings.getConnectionPoolSettings(), streamFactory,
heartbeatStreamFactory,
settings.getCredentialList(),
null,
new JMXConnectionPoolListener(),
null,
createCommandListener(settings.getCommandListeners()),
settings.getApplicationName(),
cluster的创建过程,serverFactory持有了线程池的配置,继续看在哪里使用了这个属性
public Cluster create(final ClusterSettings settings, final ServerSettings serverSettings,
final ConnectionPoolSettings connectionPoolSettings, final StreamFactory streamFactory,
final StreamFactory heartbeatStreamFactory,
final List<MongoCredential> credentialList,
final ClusterListener clusterListener, final ConnectionPoolListener connectionPoolListener,
final ConnectionListener connectionListener,
final CommandListener commandListener,
final String applicationName,
final MongoDriverInformation mongoDriverInformation) {
if (clusterListener != null) {
throw new IllegalArgumentException("Add cluster listener to ClusterSettings");
}
ClusterId clusterId = new ClusterId(settings.getDescription());
ClusterableServerFactory serverFactory = new DefaultClusterableServerFactory(clusterId, settings, serverSettings,
connectionPoolSettings, streamFactory, heartbeatStreamFactory, credentialList,
connectionListener != null ? connectionListener : new NoOpConnectionListener(),
connectionPoolListener != null ? connectionPoolListener : new NoOpConnectionPoolListener(),
commandListener, applicationName,
mongoDriverInformation != null ? mongoDriverInformation : MongoDriverInformation.builder().build());
if (settings.getMode() == ClusterConnectionMode.SINGLE) {
return new SingleServerCluster(clusterId, settings, serverFactory);
} else if (settings.getMode() == ClusterConnectionMode.MULTIPLE) {
//使用serverFactory创建cluster的实现类
return new MultiServerCluster(clusterId, settings, serverFactory);
} else {
throw new UnsupportedOperationException("Unsupported cluster mode: " + settings.getMode());
}
}
MultiServerCluster构造方法,addressTpServerTupleMap是实际的线程池
final class MultiServerCluster extends BaseCluster {
private static final Logger LOGGER = Loggers.getLogger("cluster");
private ClusterType clusterType;
private String replicaSetName;
private ObjectId maxElectionId;
private Integer maxSetVersion;
//ip+port 对应的 server
private final ConcurrentMap<ServerAddress, ServerTuple> addressToServerTupleMap =
new ConcurrentHashMap<ServerAddress, ServerTuple>();
private static final class ServerTuple {
//数据库节点服务,内含数据库连接池
private final ClusterableServer server;
//数据库节点描述
private ServerDescription description;
private ServerTuple(final ClusterableServer server, final ServerDescription description) {
this.server = server;
this.description = description;
}
}
//构造方法
public MultiServerCluster(final ClusterId clusterId, final ClusterSettings settings, final ClusterableServerFactory serverFactory) {
super(clusterId, settings, serverFactory);
isTrue("connection mode is multiple", settings.getMode() == ClusterConnectionMode.MULTIPLE);
clusterType = settings.getRequiredClusterType();
replicaSetName = settings.getRequiredReplicaSetName();
if (LOGGER.isInfoEnabled()) {
LOGGER.info(format("Cluster created with settings %s", settings.getShortDescription()));
}
ClusterDescription newDescription;
// synchronizing this code because addServer registers a callback which is re-entrant to this instance.
// In other words, we are leaking a reference to "this" from the constructor.
synchronized (this) {
//遍历url创建数据库连接
for (final ServerAddress serverAddress : settings.getHosts()) {
addServer(serverAddress);
}
newDescription = updateDescription();
}
fireChangeEvent(new ClusterDescriptionChangedEvent(clusterId, newDescription,
new ClusterDescription(settings.getMode(), ClusterType.UNKNOWN, Collections.<ServerDescription>emptyList(),
settings, serverFactory.getSettings())));
}
}
addServer<final ServerAddress serverAddress> 方法具体实现
private void addServer(final ServerAddress serverAddress) {
if (!addressToServerTupleMap.containsKey(serverAddress)) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info(format("Adding discovered server %s to client view of cluster", serverAddress));
}
ClusterableServer server = createServer(serverAddress, new DefaultServerStateListener());
addressToServerTupleMap.put(serverAddress, new ServerTuple(server, getConnectingServerDescription(serverAddress)));
}
}
createServer方法具体实现
protected ClusterableServer createServer(final ServerAddress serverAddress,
final ServerListener serverListener) {
ClusterableServer server = serverFactory.create(serverAddress, serverListener);
return server;
}
serverFactory.create方法具体实现
@Override
public ClusterableServer create(final ServerAddress serverAddress, final ServerListener serverListener) {
ConnectionPool connectionPool = new DefaultConnectionPool(
new ServerId(clusterId, serverAddress),
new InternalStreamConnectionFactory(
streamFactory,
credentialList,
connectionListener,
applicationName,
mongoDriverInformation),
connectionPoolSettings,
connectionPoolListener);
ServerMonitorFactory serverMonitorFactory = newDefaultServerMonitorFactory(
new ServerId(clusterId, serverAddress),
settings,
new InternalStreamConnectionFactory(
heartbeatStreamFactory,
credentialList,
connectionListener,
applicationName,
mongoDriverInformation),
connectionPool);
List<ServerListener> serverListeners = new ArrayList<ServerListener>();
if (serverListener != null) {
serverListeners.add(serverListener);
}
serverListeners.addAll(settings.getServerListeners());
return new DefaultServer(
new ServerId(clusterId, serverAddress),
clusterSettings.getMode(),
connectionPool,
new DefaultConnectionFactory(),
serverMonitorFactory,
serverListeners,
commandListener);
}