前言
本文旨在对阅读源代码的过程进行总结,深度揭示其工作原理,以及信息是如何被逐层读取的,并着重探讨关键数据的来源。
编译代码
代码版本选用2.26.0的分支代码编译花了17分钟
梳理流程
测试用例
org/apache/activemq/artemis/jms/tests/TopicTest.java
代码语言:javascript复制@Testpublic void testTopic() throws Exception { Connection conn = createConnection();
Session s = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer p = s.createProducer(ActiveMQServerTestCase.topic1);
MessageConsumer c = s.createConsumer(ActiveMQServerTestCase.topic1);
conn.start();
p.send(s.createTextMessage("payload"));
TextMessage m = (TextMessage) c.receive();
ProxyAssertSupport.assertEquals("payload", m.getText());
}
消息的读取
org.apache.activemq.artemis.jms.client.ActiveMQTextMessage#doBeforeReceive
代码语言:javascript复制@Overridepublic void doBeforeReceive() throws ActiveMQException {
super.doBeforeReceive();
// 读取数据的核心代码
text = readBodyText(message.getBodyBuffer());
}
进入super.doBeforeReceive()方法里面这里显示从仓库中标记当前的读取的位置到缓存中Repositions the current {@code readerIndex} to the marked* {@code readerIndex} in this buffer.
代码语言:javascript复制public void doBeforeReceive() throws ActiveMQException {
message.checkCompletion();
ActiveMQBuffer body = message.getBodyBuffer();
if (body != null) {
body.resetReaderIndex();
}
}
最后都去文本读取在这个方法里
org.apache.activemq.artemis.api.core.SimpleString#readSimpleString(io.netty.buffer.ByteBuf, int)
ActiveMQBuffer body = message.getBodyBuffer()
好奇messag跟着代码查创建TextMessage的时候根据session创建了new ActiveMQTextMessage(session); text消息
然后又根据消息里面的ClientMessage读取message.getBodyBuffer()获取ResetLimitWrappedActiveMQBuffer完成消息的读取
消息的接收
知道了消息的读取,那么消息从哪里接收呢?
org.apache.activemq.artemis.core.client.impl.ClientConsumerImpl#receive(long, boolean)
获取消息重点还是得看这段代码m = buffer.poll(),buffer是一个PriorityLinkedList集合获取到用户连接。
代码语言:javascript复制while (true) {
ClientMessageInternal m = null;
synchronized (this) {
while ((stopped || (m = buffer.poll()) == null) && !closed && toWait > 0) {
然后从buffer里面读取byte数组
org.apache.activemq.artemis.api.core.SimpleString#readSimpleString(io.netty.buffer.ByteBuf, int)
代码语言:javascript复制byte[] data = new byte[length];
buffer.readBytes(data);
return new SimpleString(data);
总结
看源码不能一次全部搞懂所有代码,只能先看主干,之后再看细枝末节,所以先总结到获取消息部分,这是一个系列的一部份代码。在阅读开源项目源码时,我们需要从整体把握到逐步深入,从顶层设计到底层实现,从主干流程到细节部分,从常规情况到特殊情况,不断深入和拓展自己的知识和技能。
引用
https://activemq.apache.org/components/artemis/documentation/hacking-guide/