Messages in ActiveMQ all inherit from the org.apache.activemq.command.BaseCommand class.
The call stack of broker processing messages is as follows:
The TransportConnection class implements the CommandVisitor interface, which describes the logic for handling various messages.
public class TransportConnection implements Connection, Task, CommandVisitor { @Override public Response service(Command command) { ... // command is the message. Take ProducerInfo as an example response = command.visit( this ); ... } @Override public Response processAddProducer(ProducerInfo info) throws Exception { SessionId sessionId = info.getProducerId().getParentId(); ConnectionId connectionId = sessionId.getParentId(); TransportConnectionState cs = lookupConnectionState(connectionId); if (cs == null) { throw new IllegalStateException("Cannot add a producer to a connection that had not been registered: " + connectionId); } SessionState ss = cs.getSessionState(sessionId); if (ss == null) { throw new IllegalStateException("Cannot add a producer to a session that had not been registered: " + sessionId); } // Avoid replaying dup commands if (!ss.getProducerIds().contains(info.getProducerId())) { ActiveMQDestination destination = info.getDestination(); if (destination != null && !AdvisorySupport.isAdvisoryTopic(destination)) { if (getProducerCount(connectionId) >= connector.getMaximumProducersAllowedPerConnection()){ throw new IllegalStateException("Can't add producer on connection " + connectionId + ": at maximum limit: " + connector.getMaximumProducersAllowedPerConnection()); } } broker.addProducer(cs.getContext(), info); try { ss.addProducer(info); } catch (IllegalStateException e) { broker.removeProducer(cs.getContext(), info); } } return null; } } // org.apache.activemq.command.ProducerInfo public Response visit(CommandVisitor visitor) throws Exception { return visitor.processAddProducer(this); }