作为一个消息中间件,有客户端和服务端两部分代码,这次的源码解析系列主要从客户端的代码入手,分成建立连接、消息发送、消息消费三个部分。趁着我昨天弄明白了源码编译的兴奋劲头还没过去,今天研究一下建立连接的部分。
如果读起来吃力,代码部分可以略过,我把主要的功能点给加粗。
通常来说,客户端使用MQ的API建立时,可以分成两个步骤:
- 对于连接的配置,比如服务器IP地址,用户名和密码等等
- 建立连接并启动
客户端示例代码:
ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(username,password,url);
ActiveMQConnection connection = connectionFactory.createConnection();
connection.start();
可以看到主要的方法是ActiveMQConnectionFactory的构造函数,和createConnection(),以及connection中的start()方法。
ActiveMQConnectionFactory中的createConnection
构造函数比较简单,直接把传入的用户名密码和url放在变量里
public ActiveMQConnectionFactory(String userName, String password, URI brokerURL) {
setUserName(userName);
setPassword(password);
setBrokerURL(brokerURL.toString());
}
createConnection方法指向了createActiveMQConnection方法,该方法中主要做的事情有三个:
- 建立Transport和通过Transport建立Connection
- 配置Connection,建立好的Transport对象会被放到Connection对象中
- 启动Transport
//建立Transport和通过Transport建立Connection
Transport transport = createTransport();
connection = createActiveMQConnection(transport, factoryStats);
//配置
connection.setUserName(userName);
connection.setPassword(password);
configureConnection(connection);
//启动Transport
transport.start();
configureConnection(connection);这个方法的作用是对实例化出的ActiveMQConnetion对象中的参数的一系列配置,代码有点长就不上了。
对于我们来说其实主要想看的是连接是如何建立起来的,也就是
Transport transport = createTransport();
connection = createActiveMQConnection(transport, factoryStats);
createTransport();方法中包含了对客户端传入的url的初步校验,主要是验证URL的合法性,而后调用工厂类TransportFactory.connection(url)来进行连接的建立。
我们客户端在建立连接的时候,有可能有TCP、UDP等等协议,AMQ实现了简单工厂类FactoryFinder,在TransportFactory.connection(url)方法中,先是通过FactoryFinder根据用户输入的url(比如tcp://192.168.0.1)来找到使用的协议工厂TcpTransportFactory,然后使用TcpTransportFactory中的类来进行连接的建立。这个过程从代码上来看有点曲折:
- TransportFactory的connect()调用findTransportFactory方法
- findTransportFactory调用FactoryFinder类的newInstance方法
- newInstance调用ObjectFactory类的create方法
- ObejctFactory是一个接口类,实现类是StandaloneObjectFactory,其中的create方法调用自身的loadClass方法
- loadClass方法中最终找到正确的类,返回至TransportFactory中
- 如果是tcp连接,最终得到的就是一个实