背景
broker.xml中有这么一段:
<connectors>
<!-- Connector used to be announced through cluster connections and notifications -->
<connector name="artemis">tcp://localhost:61618</connector>
</connectors>
那么,artemis中是如何将URI“tcp://localhost:61618”解析成ServerLocator的呢?
URI工厂
在artemis中,URI的处理,是通过URIFactory类进行加工的。
URIFactory类位于artemis-commons包中的org.apache.activemq.artemis.utils.uri命名空间下,它的主要功能是注册URISchema、委托URISchema创建相应的对象。URIFactory类是一个模板类,用户可以指定需要通过URI创建的对象的类型T,以及创建对象时需要传入的参数类型P。比如我们想要通过URI创建ServerLocator类型的对象,则T传入ServerLocator接口类型,P传入String类型。如其名称,它采用的是工厂方法设计模式。同时它还隐藏了策略模式,通过注册URISchema方法,引入包含通过URI创建相应对象的策略的URISchema,将创建对象的策略委托给了URISchema。
URI工厂中的策略
具体注册URISchema策略的执行者是ServerLocatorParser类。该类位于artemis-core-client模块中的org.apache.activemq.artemis.uri命名空间下。该类的构造函数,直接注册了4中策略:InVM、TCP、UDP、JGroup四种SchemaURI解析及策略。
public ServerLocatorParser() {
registerSchema(new InVMServerLocatorSchema());
registerSchema(new TCPServerLocatorSchema());
registerSchema(new UDPServerLocatorSchema());
registerSchema(new JGroupsServerLocatorSchema());
}
策略的载体——URISchema类,位于artemis-commons包中的org.apache.activemq.artemis.utils.uri命名空间下。它也是一个模板类,,用户可以指定需要通过URI创建的对象的类型T,以及创建对象时需要传入的参数类型P。它的职责是提供通过URI创建相应对象的具体策略。
URISchema类是策略接口的定义,其实现类InVMServerLocatorSchema、TCPServerLocatorSchema、UDPServerLocatorSchema、JGroupsServerLocatorSchema,是具体策略的实现。四个具体策略的实现类,位于artemis-commons包中的org.apache.activemq.artemis.uri.schema.serverLocator命名空间下。
URI策略-TCP策略的实现
URISchema类采用了模板方法模式,其中要求子类必须实现internalNewObject抽象方法。我们以TCPServerLocatorSchema这个子类为例来看看它是如何实现internalNewObject抽象方法的。代码如下:
ConnectionOptions options = newConnectionOptions(uri, query);
List<TransportConfiguration> configurations = TCPTransportConfigurationSchema.getTransportConfigurations(uri, query, TransportConstants.ALLOWABLE_CONNECTOR_KEYS, name, NettyConnectorFactory.class.getName());
TransportConfiguration[] tcs = new TransportConfiguration[configurations.size()];
configurations.toArray(tcs);
if (options.isHa()) {
return ActiveMQClient.createServerLocatorWithHA(tcs);
} else {
return ActiveMQClient.createServerLocatorWithoutHA(tcs);
}
可见它主要是利用了TCPTransportConfigurationSchema的静态方法getTransportConfigurations,来根据uri解析得到TransportConfiguration对象列表,然后使用ActiveMQClient工具类的createServerLocatorWithHA或createServerLocatorWithoutHA类创建ServerLocator接口实例的。
后记
本文主要是讲解从URI创建artemis core的ServerLocator实例过程,所以不对ServerLocator作过多讲解,这儿只给出ServerLocator所处位置:
ServerLocator接口位于artemis-core-client模块中的org.apache.activemq.artemis.api.core.client命名空间下。
两个实现类,ServerLocaorInternal类和ServerLocatorImpl类,位于artemis-core-client模块中的org.apache.activemq.artemis.api.core.client.impl命名空间下。
相关模块、命名空间和类的汇总参考
artemis-commons
org.apache.activemq.artemis.utils.uri
URIFactory
URISchema
org.apache.activemq.artemis.uri.schema.serverLocator
InVMServerLocatorSchema
TCPServerLocatorSchema
UDPServerLocatorSchema
JGroupsServerLocatorSchema
artemis-core-client
org.apache.activemq.artemis.uri
ServerLocatorParser
org.apache.activemq.artemis.api.core
TransportConfiguration
org.apache.activemq.artemis.api.core.client
ServerLocator
ActiveMQClient
org.apache.activemq.artemis.api.core.client.impl
ServerLocaorInternal
ServerLocatorImpl
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。