背景

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


执着的慢行者
223 声望21 粉丝

大型电子商务系统架构师、项目管理专家