源码构建
1、从 https://github.com/apache/activemq 下载源码
git clone https://github.com/apache/activemq2、切换至 activemq-5.18.x 分支
cd activemqgit checkout activemq-5.18.x3、构建源码
mvn package -DskipTests构建成功之后,在 assembly/target 目录可以看到打包好的压缩文件。
在 Idea 中运行代码 activemq-console
在 Idea 中运行代码 activemq-console,启动 activemq:
1、在 idea 中打开项目
2、解压 assembly/target 目录下生成的压缩文件,将 conf、webapps 和 lib 目录拷贝到项目的根目录下面。
3、在idea中选中子模块 activemq-console,右击 选择 Open Module Settings —> Modules —> Dependencies,点击+(加号) —>选择 JARS or directories,把 lib 中的包(包括子目录下的)全部导入
4、配置从 activemq-console 下的 Main 类启动,在 Program arguments 添加 start
5、debug 运行 Main.java 类
在 Idea 中运行单元测试类
分析 Main.java 类的 main 方法,调用链如下:
Main.java -> ShellCommand.java -> StartCommand.java -> BrokerService.java从 BrokerService 类,可以看到启动 broker 的关键代码如下:
final BrokerService broker;try { / If no config uri, use default setting if (brokerURIs.isEmpty()) { configURI = new URI(DEFAULT_CONFIG_URI); } else { configURI = new URI(brokerURIs.get(0)); }
System.out.println("Loading message broker from: " + configURI); broker = BrokerFactory.createBroker(configURI); broker.start();
} catch (Exception e) { context.printException(new RuntimeException("Failed to execute start task. Reason: " + e, e)); throw e;}在 idea 中全局搜索 BrokerService 类,可以看到很多单元测试类都用到了 BrokerService 类。比如 activemq-broker 模块中的 BrokerServiceTest 、BrokerInterceptorsTest 、IDERunner。
BrokerInterceptorsTest 类如下:
public class BrokerInterceptorsTest { private BrokerService brokerService;
@Before public void setUp() throws Exception { brokerService = new BrokerService(); brokerService.setAdvisorySupport(true); brokerService.setPersistent(false); brokerService.setUseJmx(false); brokerService.start(); }
@After public void tearDown() throws Exception { if (brokerService != null) { brokerService.stop(); } }
@Test public void testNavigateInterceptors() throws Exception { Broker b = brokerService.getBroker(); Assert.assertTrue(b instanceof BrokerFilter);
BrokerFilter bf = (BrokerFilter) b; int count = 0; while (bf != null) { Broker next = bf.getNext(); bf = next instanceof BrokerFilter ? (BrokerFilter) next : null; count++; } / a few Broker interceptors are created because of the config (i.e. AdvisoryBroker) Assert.assertTrue(count > 1); }}debug 运行 BrokerInterceptorsTest 类,可以跟踪代码,分析 BrokerService 初始化过程。
如果想查看 TransportConnector 初始化过程,可以调试 IDERunner 类
public class IDERunner {
private static final boolean TRANSPORT_TRACE = false;
public static void main(String[]args) throws Exception { BrokerService brokerService = new BrokerService();
brokerService.addConnector( "tcp://0.0.0.0:61616?trace=" + TRANSPORT_TRACE + "&transport.wireFormat.maxFrameSize=104857600");
brokerService.setPersistent(false); brokerService.setUseJmx(false); brokerService.setAdvisorySupport(false);
brokerService.start();
brokerService.waitUntilStopped(); }}