ActiveMQConnectionFactory创建ActiveMQConnection之模式应用

本文解析了ActiveMQ中如何通过ActiveMQConnectionFactory创建连接的过程。详细介绍了TransportFactory如何根据URI和Executor生成Transport,以及FactoryFinder如何根据scheme选择合适的TransportFactory。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ActiveMQ中使用了大量的工厂模式和反射模式,下面通过ActiveMQConnectionFactory创建connection来理解一下。

       ActiveMQ实现了JMS1.1规范,同样ActiveMQConnectionFactory也是如此,客户端可以通过如下步骤来创建一个Connection:

String url = “tcp://localhost:61616”;

ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(url);

Connection conn = connectionFactory.createConnection();

 

createConnection需要如下的几个操作:

Transport              transport = createTransport();

Connection = createActivemqConnection(transport,factoryStats);

configureConnection(connection);

transport.start();

 

 

原来真正的创建socket连接是在createTransport()中实现的。

调用TransportFactory.connect(brokerURL, DEFAULT_CONNECTION_EXECUTOR);

 

TcpTransportFactory

FactoryFinder

TransportFactory

 

findTransportFactory

URI

Executor

Transport

URI

Executor

Transport

TcpTransportFactory

FactoryFinder

TransportFactory

 

findTransportFactory

URI

Executor

Transport

TcpTransportFactory

FactoryFinder

TransportFactory

 

findTransportFactory

URI

Executor

Transport

TcpTransportFactory

FactoryFinder

TransportFactory

 

findTransportFactory

URI

Executor

Transport

TcpTransportFactory

FactoryFinder

TransportFactory

 

findTransportFactory

URI

Executor

Transport

TcpTransportFactory

FactoryFinder

TransportFactory

 

findTransportFactory

URI

Executor

Transport

TcpTransportFactory

FactoryFinder

TransportFactory

 

findTransportFactory

URI

Executor

Transport

图一

如图一所示TransportFactory根据输入URI,Executor 生产TransportTransportFactory中的findTransportFactory方法调用辅助类FactoryFinder根据scheme选择合适的TransportFactory,这里选择的是TcpTransportFactory来生产Transport。这里TransportFactory当了一个工厂代理的角色。

TcpTransportFactory继承了TransportFactory。其UML图如下:

 

 

 

图二

FactoryFinder类的目的是根据scheme来生产合适的TransportFactory。生产过程如下:

 

public Object newInstance(String key, String propertyPrefix) throws IllegalAccessException, InstantiationException, IOException, ClassNotFoundException {

        if (propertyPrefix == null) {

            propertyPrefix = "";

        }

 

        Class clazz = classMap.get(propertyPrefix + key);

        if (clazz == null) {

            clazz = newInstance(doFindFactoryProperies(key), propertyPrefix);

            classMap.put(propertyPrefix + key, clazz);

        }

        return clazz.newInstance();

    }

  

首先从缓存classMap中去取,如果没有再生成一个新的实例并放入到缓存中。doFindFactoryProperies(key)负责将外部properties文件读入

 

private Properties doFindFactoryProperies(String key) throws IOException {

        String uri = path + key;

 

        // lets try the thread context class loader first

        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

        if (classLoader == null) {

            classLoader = getClass().getClassLoader();

        }

        InputStream in = classLoader.getResourceAsStream(uri);

        if (in == null) {

            in = FactoryFinder.class.getClassLoader().getResourceAsStream(uri);

            if (in == null) {

                throw new IOException("Could not find factory class for resource: " + uri);

            }

        }

 

        // lets load the file

        BufferedInputStream reader = null;

        try {

            reader = new BufferedInputStream(in);

            Properties properties = new Properties();

            properties.load(reader);

            return properties;

        } finally {

            try {

                reader.close();

            } catch (Exception e) {

            }

        }

    }

 

外部文件的内容(MeTA-INF/services/org/apache/activemq/transport/tcp):class=org.apache.activemq.transport.tcp.TcpTransportFactory

然后利用反射来生成类org.apache.activemq.transport.tcp.TcpTransportFactory的实例。

如下:

private Class newInstance(Properties properties, String propertyPrefix) throws ClassNotFoundException, IOException {

 

        String className = properties.getProperty(propertyPrefix + "class");

        if (className == null) {

            throw new IOException("Expected property is missing: " + propertyPrefix + "class");

        }

        Class clazz = null;

        ClassLoader loader = Thread.currentThread().getContextClassLoader();

        if (loader != null) {

            try {

                clazz = loader.loadClass(className);

            } catch (ClassNotFoundException e) {

                // ignore

            }

        }

        if (clazz == null) {

            clazz = FactoryFinder.class.getClassLoader().loadClass(className);

        }

 

        return clazz;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值