创建持久订阅时的代码:
@Override
public TopicSubscriber createDurableSubscriber(Topic topic, String name, String messageSelector, boolean noLocal) throws JMSException {
checkClosed();
if (topic == null) {
throw new InvalidDestinationException("Topic cannot be null");
}
if (topic instanceof CustomDestination) {
CustomDestination customDestination = (CustomDestination)topic;
return customDestination.createDurableSubscriber(this, name, messageSelector, noLocal);
}
//该行是校验是否手动指定的clientid
connection.checkClientIDWasManuallySpecified();
ActiveMQPrefetchPolicy prefetchPolicy = this.connection.getPrefetchPolicy();
int prefetch = isAutoAcknowledge() && connection.isOptimizedMessageDispatch() ? prefetchPolicy.getOptimizeDurableTopicPrefetch() : prefetchPolicy.getDurableTopicPrefetch();
int maxPrendingLimit = prefetchPolicy.getMaximumPendingMessageLimit();
return new ActiveMQTopicSubscriber(this, getNextConsumerId(), ActiveMQMessageTransformation.transformDestination(topic), name, messageSelector, prefetch, maxPrendingLimit,
noLocal, false, asyncDispatch);
}
如果没有手动指定,则抛异常:
在调用connetion.start()方法后,clientId如果没有手动指定,系统会默认 生成一个:
connection.start();
@Override
public void start() throws JMSException {
checkClosedOrFailed();
//该方法会检查连接信息,没有clientId时会默认生成一个
ensureConnectionInfoSent();
if (started.compareAndSet(false, true)) {
for (Iterator<ActiveMQSession> i = sessions.iterator(); i.hasNext();) {
ActiveMQSession session = i.next();
session.start();
}
}
}
protected void ensureConnectionInfoSent() throws JMSException {
synchronized(this.ensureConnectionInfoSentMutex) {
// Can we skip sending the ConnectionInfo packet??
if (isConnectionInfoSentToBroker || closed.get()) {
return;
}
//TODO shouldn't this check be on userSpecifiedClientID rather than the value of clientID?
//设置clientid,但设置后,由于不是手动指定而是系统生成的,userSpecifiedClientID为false
if (info.getClientId() == null || info.getClientId().trim().length() == 0) {
info.setClientId(clientIdGenerator.generateId());
}
syncSendPacket(info.copy(), getConnectResponseTimeout());
this.isConnectionInfoSentToBroker = true;
// Add a temp destination advisory consumer so that
// We know what the valid temporary destinations are on the
// broker without having to do an RPC to the broker.
ConsumerId consumerId = new ConsumerId(new SessionId(info.getConnectionId(), -1), consumerIdGenerator.getNextSequenceId());
if (watchTopicAdvisories) {
advisoryConsumer = new AdvisoryConsumer(this, consumerId);
}
}
}
在上边的方法中,设置clientid,但设置后,由于不是手动指定而是系统生成的,userSpecifiedClientID为false。