7.6. 部署连接工厂作为工件
本主题讨论实际建议。
在 部署方法 中,javax.jms.ConnectionFactory 服务直接由应用代码注册。通常,这个代码位于 Blueprint 容器中。蓝图 XML 可能是普通 OSGi 捆绑包的一部分,可使用 mvn: URI 进行安装,并存储在 Maven 存储库中(本地或远程)。与配置管理员配置相比,版本控制等捆绑包更容易。
pax-jms-config 版本 1.0.0 捆绑包为 连接工厂 配置添加部署方法。应用程序开发人员注册 javax.jms.(XA)ConnectionFactory 服务(通常使用 Bluerpint XML)并指定服务属性。然后,pax-jms-config 检测到注册的、代理特定连接工厂和(使用服务属性)将服务嵌套在通用、非代理特定的连接池中。
以下是使用 Blueprint XML 的三种 部署方法。
7.6.1. 手动部署连接因素 复制链接链接已复制到粘贴板!
在此方法中,不需要 pax-jms-config 捆绑包。应用程序代码负责注册特定于代理和通用连接池。
<!--
Broker-specific, non-pooling, non-enlisting javax.jms.XAConnectionFactory
-->
<bean id="artemis" class="org.apache.activemq.artemis.jms.client.ActiveMQXAConnectionFactory">
<argument value="tcp://localhost:61616" />
<property name="callTimeout" value="2000" />
<property name="initialConnectAttempts" value="3" />
</bean>
<!--
Fuse exports this service from fuse-pax-transx-tm-narayana bundle.
-->
<reference id="tm" interface="javax.transaction.TransactionManager" />
<!--
Non broker-specific, generic, pooling, enlisting javax.jms.ConnectionFactory
-->
<bean id="pool" class="org.messaginghub.pooled.jms.JmsPoolXAConnectionFactory">
<property name="connectionFactory" ref="artemis" />
<property name="transactionManager" ref="tm" />
<property name="maxConnections" value="10" />
<property name="idleTimeout" value="10000" />
</bean>
<!--
Expose connection factory for use by application code (such as Camel, Spring, ...)
-->
<service interface="javax.jms.ConnectionFactory" ref="pool">
<service-properties>
<!-- Giving connection factory a name using one of these properties makes identification easier in jms:connectionfactories: -->
<entry key="osgi.jndi.service.name" value="jms/artemis" />
<!--<entry key="name" value="jms/artemis" />-->
<!-- Without any of the above, name will fall back to "service.id" -->
</service-properties>
</service>
<!--
Broker-specific, non-pooling, non-enlisting javax.jms.XAConnectionFactory
-->
<bean id="artemis" class="org.apache.activemq.artemis.jms.client.ActiveMQXAConnectionFactory">
<argument value="tcp://localhost:61616" />
<property name="callTimeout" value="2000" />
<property name="initialConnectAttempts" value="3" />
</bean>
<!--
Fuse exports this service from fuse-pax-transx-tm-narayana bundle.
-->
<reference id="tm" interface="javax.transaction.TransactionManager" />
<!--
Non broker-specific, generic, pooling, enlisting javax.jms.ConnectionFactory
-->
<bean id="pool" class="org.messaginghub.pooled.jms.JmsPoolXAConnectionFactory">
<property name="connectionFactory" ref="artemis" />
<property name="transactionManager" ref="tm" />
<property name="maxConnections" value="10" />
<property name="idleTimeout" value="10000" />
</bean>
<!--
Expose connection factory for use by application code (such as Camel, Spring, ...)
-->
<service interface="javax.jms.ConnectionFactory" ref="pool">
<service-properties>
<!-- Giving connection factory a name using one of these properties makes identification easier in jms:connectionfactories: -->
<entry key="osgi.jndi.service.name" value="jms/artemis" />
<!--<entry key="name" value="jms/artemis" />-->
<!-- Without any of the above, name will fall back to "service.id" -->
</service-properties>
</service>
以下是显示如何使用它的 shell 命令:
karaf@root()> feature:install artemis-core-client artemis-jms-client karaf@root()> install -s mvn:org.apache.commons/commons-pool2/2.5.0 Bundle ID: 244 karaf@root()> install -s mvn:org.messaginghub/pooled-jms/0.3.0 Bundle ID: 245 karaf@root()> install -s blueprint:file://$PQ_HOME/message-brokers/blueprints/artemis-manual.xml Bundle ID: 246 karaf@root()> bundle:services -p 246 Bundle 246 provides: -------------------- objectClass = [javax.jms.ConnectionFactory] osgi.jndi.service.name = jms/artemis osgi.service.blueprint.compname = pool service.bundleid = 246 service.id = 340 service.scope = bundle ----- objectClass = [org.osgi.service.blueprint.container.BlueprintContainer] osgi.blueprint.container.symbolicname = artemis-manual.xml osgi.blueprint.container.version = 0.0.0 service.bundleid = 246 service.id = 341 service.scope = singleton karaf@root()> feature:install jms karaf@root()> jms:connectionfactories JMS Connection Factory ────────────────────── jms/artemis karaf@root()> jms:info -u admin -p admin jms/artemis Property │ Value ─────────┼────────────────────────── product │ ActiveMQ version │ 2.4.0.amq-711002-redhat-1
karaf@root()> feature:install artemis-core-client artemis-jms-client
karaf@root()> install -s mvn:org.apache.commons/commons-pool2/2.5.0
Bundle ID: 244
karaf@root()> install -s mvn:org.messaginghub/pooled-jms/0.3.0
Bundle ID: 245
karaf@root()> install -s blueprint:file://$PQ_HOME/message-brokers/blueprints/artemis-manual.xml
Bundle ID: 246
karaf@root()> bundle:services -p 246
Bundle 246 provides:
--------------------
objectClass = [javax.jms.ConnectionFactory]
osgi.jndi.service.name = jms/artemis
osgi.service.blueprint.compname = pool
service.bundleid = 246
service.id = 340
service.scope = bundle
-----
objectClass = [org.osgi.service.blueprint.container.BlueprintContainer]
osgi.blueprint.container.symbolicname = artemis-manual.xml
osgi.blueprint.container.version = 0.0.0
service.bundleid = 246
service.id = 341
service.scope = singleton
karaf@root()> feature:install jms
karaf@root()> jms:connectionfactories
JMS Connection Factory
──────────────────────
jms/artemis
karaf@root()> jms:info -u admin -p admin jms/artemis
Property │ Value
─────────┼──────────────────────────
product │ ActiveMQ
version │ 2.4.0.amq-711002-redhat-1
如上方列表所示,Bartner 捆绑包将导出 javax.jms.ConnectionFactory 服务,该服务是一个通用、非特定于代理的连接池。特定于代理的 javax.jms.XAConnectionFactory 没有 注册为 OSGi 服务,因为 Blueprint XML 没有明确的 < service ref="artemis"> 声明。
7.6.2. 连接工厂部署 复制链接链接已复制到粘贴板!
此方法以 规范 的方式显示使用 pax-jms-config。这与 Fuse 6.x 推荐的方法稍有不同,因为要求将配置指定为服务属性。
下面是蓝图 XML 示例:
<!--
A broker-specific org.ops4j.pax.jms.service.ConnectionFactoryFactory that can create (XA)ConnectionFactory
using properties. It is registered by pax-jms-* bundles
-->
<reference id="connectionFactoryFactory"
interface="org.ops4j.pax.jms.service.ConnectionFactoryFactory"
filter="(type=artemis)" />
<!--
Non broker-specific org.ops4j.pax.jms.service.PooledConnectionFactoryFactory that can create
pooled connection factories with the help of org.ops4j.pax.jms.service.ConnectionFactoryFactory
For example, pax-jms-pool-pooledjms bundle registers org.ops4j.pax.jms.service.PooledConnectionFactoryFactory
with these properties:
- pool = pooledjms
- xa = true|false (both are registered)
-->
<reference id="pooledConnectionFactoryFactory"
interface="org.ops4j.pax.jms.service.PooledConnectionFactoryFactory"
filter="(&(pool=pooledjms)(xa=true))" />
<!--
When using XA connection factories, javax.transaction.TransactionManager service is not needed here.
It is used internally by xa-aware pooledConnectionFactoryFactory.
-->
<!--<reference id="tm" interface="javax.transaction.TransactionManager" />-->
<!--
Finally, use both factories to expose the pooled, xa-aware, connection factory.
-->
<bean id="pool" factory-ref="pooledConnectionFactoryFactory" factory-method="create">
<argument ref="connectionFactoryFactory" />
<argument>
<props>
<!--
Properties needed by artemis-specific org.ops4j.pax.jms.service.ConnectionFactoryFactory
-->
<prop key="jms.url" value="tcp://localhost:61616" />
<prop key="jms.callTimeout" value="2000" />
<prop key="jms.initialConnectAttempts" value="3" />
<!-- Properties needed by pooled-jms-specific org.ops4j.pax.jms.service.PooledConnectionFactoryFactory -->
<prop key="pool.maxConnections" value="10" />
<prop key="pool.idleTimeout" value="10000" />
</props>
</argument>
</bean>
<!--
Expose connection factory for use by application code (such as Camel, Spring, ...)
-->
<service interface="javax.jms.ConnectionFactory" ref="pool">
<service-properties>
<!-- Giving connection factory a name using one of these properties makes identification easier in jms:connectionfactories: -->
<entry key="osgi.jndi.service.name" value="jms/artemis" />
<!--<entry key="name" value="jms/artemis" />-->
<!-- Without any of the above, name will fall back to "service.id" -->
</service-properties>
</service>
<!--
A broker-specific org.ops4j.pax.jms.service.ConnectionFactoryFactory that can create (XA)ConnectionFactory
using properties. It is registered by pax-jms-* bundles
-->
<reference id="connectionFactoryFactory"
interface="org.ops4j.pax.jms.service.ConnectionFactoryFactory"
filter="(type=artemis)" />
<!--
Non broker-specific org.ops4j.pax.jms.service.PooledConnectionFactoryFactory that can create
pooled connection factories with the help of org.ops4j.pax.jms.service.ConnectionFactoryFactory
For example, pax-jms-pool-pooledjms bundle registers org.ops4j.pax.jms.service.PooledConnectionFactoryFactory
with these properties:
- pool = pooledjms
- xa = true|false (both are registered)
-->
<reference id="pooledConnectionFactoryFactory"
interface="org.ops4j.pax.jms.service.PooledConnectionFactoryFactory"
filter="(&(pool=pooledjms)(xa=true))" />
<!--
When using XA connection factories, javax.transaction.TransactionManager service is not needed here.
It is used internally by xa-aware pooledConnectionFactoryFactory.
-->
<!--<reference id="tm" interface="javax.transaction.TransactionManager" />-->
<!--
Finally, use both factories to expose the pooled, xa-aware, connection factory.
-->
<bean id="pool" factory-ref="pooledConnectionFactoryFactory" factory-method="create">
<argument ref="connectionFactoryFactory" />
<argument>
<props>
<!--
Properties needed by artemis-specific org.ops4j.pax.jms.service.ConnectionFactoryFactory
-->
<prop key="jms.url" value="tcp://localhost:61616" />
<prop key="jms.callTimeout" value="2000" />
<prop key="jms.initialConnectAttempts" value="3" />
<!-- Properties needed by pooled-jms-specific org.ops4j.pax.jms.service.PooledConnectionFactoryFactory -->
<prop key="pool.maxConnections" value="10" />
<prop key="pool.idleTimeout" value="10000" />
</props>
</argument>
</bean>
<!--
Expose connection factory for use by application code (such as Camel, Spring, ...)
-->
<service interface="javax.jms.ConnectionFactory" ref="pool">
<service-properties>
<!-- Giving connection factory a name using one of these properties makes identification easier in jms:connectionfactories: -->
<entry key="osgi.jndi.service.name" value="jms/artemis" />
<!--<entry key="name" value="jms/artemis" />-->
<!-- Without any of the above, name will fall back to "service.id" -->
</service-properties>
</service>
上例使用 factory an 使用 connection factory factories(…)创建连接工厂。不需要明确引用 javax.transaction.TransactionManager 服务,因为它由 XA 感知池ed ConnectionFactoryonnectionFactoryy 内部跟踪。
以下是它在 Fuse/Karaf shell 中查找的方式:
karaf@root()> feature:install jms pax-jms-artemis pax-jms-pool-pooledjms karaf@root()> install -s blueprint:file://$PQ_HOME/message-brokers/blueprints/artemis-pax-jms-factory-pooledjms.xml Bundle ID: 253 karaf@root()> bundle:services -p 253 Bundle 253 provides: -------------------- objectClass = [javax.jms.ConnectionFactory] osgi.jndi.service.name = jms/artemis osgi.service.blueprint.compname = pool service.bundleid = 253 service.id = 347 service.scope = bundle ----- objectClass = [org.osgi.service.blueprint.container.BlueprintContainer] osgi.blueprint.container.symbolicname = artemis-pax-jms-factory-pooledjms.xml osgi.blueprint.container.version = 0.0.0 service.bundleid = 253 service.id = 348 service.scope = singleton karaf@root()> jms:connectionfactories JMS Connection Factory ────────────────────── jms/artemis karaf@root()> jms:info -u admin -p admin jms/artemis Property │ Value ─────────┼────────────────────────── product │ ActiveMQ version │ 2.4.0.amq-711002-redhat-1
karaf@root()> feature:install jms pax-jms-artemis pax-jms-pool-pooledjms
karaf@root()> install -s blueprint:file://$PQ_HOME/message-brokers/blueprints/artemis-pax-jms-factory-pooledjms.xml
Bundle ID: 253
karaf@root()> bundle:services -p 253
Bundle 253 provides:
--------------------
objectClass = [javax.jms.ConnectionFactory]
osgi.jndi.service.name = jms/artemis
osgi.service.blueprint.compname = pool
service.bundleid = 253
service.id = 347
service.scope = bundle
-----
objectClass = [org.osgi.service.blueprint.container.BlueprintContainer]
osgi.blueprint.container.symbolicname = artemis-pax-jms-factory-pooledjms.xml
osgi.blueprint.container.version = 0.0.0
service.bundleid = 253
service.id = 348
service.scope = singleton
karaf@root()> jms:connectionfactories
JMS Connection Factory
──────────────────────
jms/artemis
karaf@root()> jms:info -u admin -p admin jms/artemis
Property │ Value
─────────┼──────────────────────────
product │ ActiveMQ
version │ 2.4.0.amq-711002-redhat-1
如上方列表所示,Bartner 捆绑包将导出 javax.jms.ConnectionFactory 服务,该服务是一个通用、非特定于代理的连接池。代理特定 javax.jms.XAConnectionFactory 没有 注册为 OSGi 服务,因为 Blueprint XML 没有明确的 < service ref="artemis"> 声明。
7.6.3. 连接工厂的混合部署 复制链接链接已复制到粘贴板!
pax-jms-config 1.0.0 bundle 使用服务属性添加了另一种 嵌套 代理特定连接工厂中的一种方式。此方法与在 Fuse 6.x 中工作的方式匹配。
下面是蓝图 XML 示例:
<!--
Broker-specific, non-pooling, non-enlisting javax.jms.XAConnectionFactory
-->
<bean id="artemis" class="org.apache.activemq.artemis.jms.client.ActiveMQXAConnectionFactory">
<argument value="tcp://localhost:61616" />
<property name="callTimeout" value="2000" />
<property name="initialConnectAttempts" value="3" />
</bean>
<!--
Expose broker-specific connection factory with service properties.
No need to expose pooling, enlisting, non broker-specific javax.jms.XAConnectionFactory. It will be registered
automatically by pax-jms-config with the same properties as this <service>, but with a higher service.ranking
-->
<service id="pool" ref="artemis" interface="javax.jms.XAConnectionFactory">
<service-properties>
<!-- "pool" key is needed for pax-jms-config to wrap broker-specific connection factory inside connection pool -->
<entry key="pool" value="pooledjms" />
<!-- <service>/@id attribute does not propagate, but name of the connection factory is required using one of: -->
<entry key="osgi.jndi.service.name" value="jms/artemis" />
<!-- or: -->
<!--<entry key="name" value="jms/artemis" />-->
<!-- Other properties, that normally by e.g., pax-jms-pool-pooledjms -->
<entry key="pool.maxConnections" value="10" />
<entry key="pool.idleTimeout" value="10000" />
</service-properties>
</service>
<!--
Broker-specific, non-pooling, non-enlisting javax.jms.XAConnectionFactory
-->
<bean id="artemis" class="org.apache.activemq.artemis.jms.client.ActiveMQXAConnectionFactory">
<argument value="tcp://localhost:61616" />
<property name="callTimeout" value="2000" />
<property name="initialConnectAttempts" value="3" />
</bean>
<!--
Expose broker-specific connection factory with service properties.
No need to expose pooling, enlisting, non broker-specific javax.jms.XAConnectionFactory. It will be registered
automatically by pax-jms-config with the same properties as this <service>, but with a higher service.ranking
-->
<service id="pool" ref="artemis" interface="javax.jms.XAConnectionFactory">
<service-properties>
<!-- "pool" key is needed for pax-jms-config to wrap broker-specific connection factory inside connection pool -->
<entry key="pool" value="pooledjms" />
<!-- <service>/@id attribute does not propagate, but name of the connection factory is required using one of: -->
<entry key="osgi.jndi.service.name" value="jms/artemis" />
<!-- or: -->
<!--<entry key="name" value="jms/artemis" />-->
<!-- Other properties, that normally by e.g., pax-jms-pool-pooledjms -->
<entry key="pool.maxConnections" value="10" />
<entry key="pool.idleTimeout" value="10000" />
</service-properties>
</service>
在上例中,您可以看到仅手动注册代理特定连接工厂。pool=pooledjms 服务属性是连接工厂跟踪器的提示,它由 pax-jms-config 捆绑包管理。带有这个 service 属性的连接工厂服务封装在池工厂内,在本示例中,pax-jms-pool-pooledjms。
以下是它在 Fuse/Karaf shell 中查找的方式:
karaf@root()> feature:install jms pax-jms-config pax-jms-artemis pax-jms-pool-pooledjms karaf@root()> install -s blueprint:file://$PQ_HOME/message-brokers/blueprints/artemis-pax-jms-discovery.xml Bundle ID: 254 karaf@root()> bundle:services -p 254 Bundle 254 provides: -------------------- objectClass = [javax.jms.XAConnectionFactory] osgi.jndi.service.name = jms/artemis osgi.service.blueprint.compname = artemis pool = pooledjms pool.idleTimeout = 10000 pool.maxConnections = 10 service.bundleid = 254 service.id = 349 service.scope = bundle ----- objectClass = [org.osgi.service.blueprint.container.BlueprintContainer] osgi.blueprint.container.symbolicname = artemis-pax-jms-discovery.xml osgi.blueprint.container.version = 0.0.0 service.bundleid = 254 service.id = 351 service.scope = singleton karaf@root()> service:list javax.jms.XAConnectionFactory [javax.jms.XAConnectionFactory] ------------------------------- osgi.jndi.service.name = jms/artemis osgi.service.blueprint.compname = artemis pool = pooledjms pool.idleTimeout = 10000 pool.maxConnections = 10 service.bundleid = 254 service.id = 349 service.scope = bundle Provided by : Bundle 254 Used by: OPS4J Pax JMS Config (251) karaf@root()> service:list javax.jms.ConnectionFactory [javax.jms.ConnectionFactory] ----------------------------- osgi.jndi.service.name = jms/artemis osgi.service.blueprint.compname = artemis pax.jms.managed = true pax.jms.service.id.ref = 349 pool.idleTimeout = 10000 pool.maxConnections = 10 service.bundleid = 251 service.id = 350 service.ranking = 1000 service.scope = singleton Provided by : OPS4J Pax JMS Config (251) karaf@root()> jms:connectionfactories JMS Connection Factory ────────────────────── jms/artemis karaf@root()> jms:info -u admin -p admin jms/artemis Property │ Value ─────────┼────────────────────────── product │ ActiveMQ version │ 2.4.0.amq-711002-redhat-1
karaf@root()> feature:install jms pax-jms-config pax-jms-artemis pax-jms-pool-pooledjms
karaf@root()> install -s blueprint:file://$PQ_HOME/message-brokers/blueprints/artemis-pax-jms-discovery.xml
Bundle ID: 254
karaf@root()> bundle:services -p 254
Bundle 254 provides:
--------------------
objectClass = [javax.jms.XAConnectionFactory]
osgi.jndi.service.name = jms/artemis
osgi.service.blueprint.compname = artemis
pool = pooledjms
pool.idleTimeout = 10000
pool.maxConnections = 10
service.bundleid = 254
service.id = 349
service.scope = bundle
-----
objectClass = [org.osgi.service.blueprint.container.BlueprintContainer]
osgi.blueprint.container.symbolicname = artemis-pax-jms-discovery.xml
osgi.blueprint.container.version = 0.0.0
service.bundleid = 254
service.id = 351
service.scope = singleton
karaf@root()> service:list javax.jms.XAConnectionFactory
[javax.jms.XAConnectionFactory]
-------------------------------
osgi.jndi.service.name = jms/artemis
osgi.service.blueprint.compname = artemis
pool = pooledjms
pool.idleTimeout = 10000
pool.maxConnections = 10
service.bundleid = 254
service.id = 349
service.scope = bundle
Provided by :
Bundle 254
Used by:
OPS4J Pax JMS Config (251)
karaf@root()> service:list javax.jms.ConnectionFactory
[javax.jms.ConnectionFactory]
-----------------------------
osgi.jndi.service.name = jms/artemis
osgi.service.blueprint.compname = artemis
pax.jms.managed = true
pax.jms.service.id.ref = 349
pool.idleTimeout = 10000
pool.maxConnections = 10
service.bundleid = 251
service.id = 350
service.ranking = 1000
service.scope = singleton
Provided by :
OPS4J Pax JMS Config (251)
karaf@root()> jms:connectionfactories
JMS Connection Factory
──────────────────────
jms/artemis
karaf@root()> jms:info -u admin -p admin jms/artemis
Property │ Value
─────────┼──────────────────────────
product │ ActiveMQ
version │ 2.4.0.amq-711002-redhat-1
在上例中,jms:connectionfactories 仅显示一个服务,因为此命令会删除重复的名称。jdbc:ds-list 在数据源混合部署中介绍了两种服务。
javax.jms.XAConnectionFactory 从 Blueprint 捆绑包注册,它含有 pool = pooledjms 属性。
javax.jms.ConnectionFactory 从 pax-jms-config 捆绑包中注册,并且:
-
它没有
pool = pooledjms属性。在注册打包程序连接工厂时会删除它。 -
它具有
service.ranking = 1000属性,因此它始终是何时首选版本,例如查找连接工厂的名称。 -
它具有
pax.jms.managed = true属性,因此它不会尝试再次换行。 -
它具有
pax.jms.service.id.ref = 349属性,它指示在连接池中嵌套的原始连接工厂服务。