7.2使用Spring嵌入ActiveMQ

ActiveMQ is developed with Spring in mind。事实上,ActiveMQ默认使用Spring XML配置文件。这使它很容易嵌入到Spring有效的应用中。这节将探索徐东使用Spring的ActiveMQ的方法。虽然一些方法既有优点也有缺点,并且一些比另一些更被推荐,但没有一种单独的方法时最好的。使用哪种方法普遍决定于对你的应用和系统结构的考虑,你的开发者的技能集,和一旦部署到你的生产系统后维护解决方案的难度。
7.2.1纯Spring XML
要了解的第一种风格的Spring配置是所谓的纯Spring配置。一个纯粹的Spring配置的特点是XML风格。在配置文件中它使用基本的Spring <bean id="..." class="...">的XML风格。这种XML风格众所周知,因为Spring是非常普遍和易于理解的。
对于ActiveMQ,使用纯Spring XML语法是很简单的。你所要做的就是定义BrokerService(作为一个bean)和在Spring配置文件中的任何依赖。下表类似于显示在表7.2中的代理配置:

Listing 7.6 A pure Spring configuration for ActiveMQ
<beans>
<bean id="admins" class="org.apache.activemq.security.AuthenticationUser">
<constructor-arg index="0" value="admin" />
<constructor-arg index="1" value="password" />
<constructor-arg index="2" value="admins,publisher,consumers" />
</bean>
<bean id="publishers" class="org.apache.activemq.security.AuthenticationUser">
<constructor-arg index="0" value="publisher" />
<constructor-arg index="1" value="password" />
<constructor-arg index="2" value="publisher,consumers" />
</bean>
<bean id="consumers" class="org.apache.activemq.security.AuthenticationUser">
<constructor-arg index="0" value="consumer" />
<constructor-arg index="1" value="password" />
<constructor-arg index="2" value="consumers" />
</bean>
<bean id="guests" class="org.apache.activemq.security.AuthenticationUser">
<constructor-arg index="0" value="guest" />
<constructor-arg index="1" value="password" />
<constructor-arg index="2" value="guests" />
</bean>
<bean id="simpleAuthPlugin" class="org.apache.activemq.security.SimpleAuthenticationPlugin">
<property name="users">
<util:list>
<ref bean="admins" />
<ref bean="publishers" />
<ref bean="consumers" />
<ref bean="guests" />
</util:list>
</property>
</bean>
<bean id="broker" class="org.apache.activemq.broker.BrokerService" init-method="start" destroy-method="stop">
<property name="brokerName" value="myBroker" />
<property name="persistent" value="false" />
<property name="transportConnectorURIs">
<list>
<value>tcp://localhost:61616</value>
</list>
</property>
<property name="plugins">
<list>
<ref bean="simpleAuthPlugin"/>
</list>
</property>
</bean>
</beans>

如所提到的,在表7.6的代理配置完全遵照了表7.2中的相同代理配置。这两个配置间的不同在于表7.2直接使用ActiveMQ的Java API,而表7.6通过Spring容器和纯Spring风格的XML间接使用了ActiveMQ的Java API。这里没有明显的必然优势;这仅仅是一个有效的可选项。即使你在配置文件中使用了基本的ActiveMQ XML,你依然也能在那个文件中使用Spring XML 语法。
为了启动使用这个风格配置的ActiveMQ,使用如下所示的SpringConfig类:

Listing 7.7 Start ActiveMQ using a pure Spring XML syntax
$ mvn exec:java \
-Dexec.mainClass=org.apache.activemq.book.ch7.broker.SpringConfig
...
13:27:42,125 | INFO | Loading XML bean definitions from class path
resource [org/apache/activemq/book/ch7/pure-spring.xml]
13:27:42,366 | INFO | Bean factory for application context
[org.springframework.context.support.
ClassPathXmlApplicationContext@20edbca8]:
org.springframework.beans.factory.support.
DefaultListableBeanFactory@7c959fa1
13:27:42,418 | INFO | Pre-instantiating singletons in
org.springframework.beans.factory.support.
DefaultListableBeanFactory@7c959fa1:
defining beans
[admins,publishers,consumers,guests,simpleAuthPlugin,broker];
root of factory hierarchy
13:27:42,719 | INFO | Using Persistence Adapter: MemoryPersistenceAdapter
13:27:42,721 | INFO | ActiveMQ 5.4.1 JMS Message Broker (myBroker) is
starting
13:27:42,721 | INFO | For help or more information please see:
http://activemq.apache.org/
13:27:43,224 | INFO | Listening for connections at:
tcp://mongoose.local:61616
13:27:43,225 | INFO | Connector tcp://mongoose.local:61616 Started
13:27:43,227 | INFO | ActiveMQ JMS Message Broker
(myBroker, ID:mongoose.local-50630-1282246062743-0:0) started

SpringConfig是一个简单类,它在一个main方法中使用Spring的ClassPathXmlApplicationContext( http://mng.bz/71U2)来在纯Spring配置中读取并启动ActiveMQ 代理。在这个风格的启动上稍有不同的是使用了BrokerFactoryBean(provided with ActiveMQ)。
7.2.2使用BrokerFactoryBean
在企业型Java开发中使用Spring工厂beans( http://mng.bz/h0OJ)来expose他们自己工厂的beans是很普遍的。Spring工厂beans的目的是instantiate一个需要复杂配置的工厂。这个工厂bean的使用替代了一堆复杂的XML的书写,并且它hooks right into Spring容器。org.apache.activemq.xbean。BrokerFactoryBean为ActiveMQ工作。为了这个目的使用BrokerFactoryBean比建立和维护你自己的类容易。ActiveMQ代理能像下面所示一样使用BrokerFactoryBean类启动。

Listing 7.8 ActiveMQ XML configuration for projects using Spring syntax
<beans>
  <bean id="broker" class="org.apache.activemq.xbean.BrokerFactoryBean">
    <property name="config" value="org/apache/activemq/book/ch6/activemq-simple.xml"/>
    <property name="start" value="true" />
  </bean>
</beans>

注意表7.8中配置BrokerFactoryBean的XML是minimal的。它使用一个名为config的属性来指向在前面章节表述的基本的ActiveMQ XML 配置文件,和一个名为start的属性来instruct Spring来在工厂bean初始化以后invoke 工厂bean的start方法(它启动了ActiveMQ代理的实例)。你也可以不激活这个特性并简单地手动启动。为了执行这个示例,看下下面的列表。

Listing 7.9 Start ActiveMQ using the BrokerFactoryBean
$ mvn exec:java \
-Dexec.mainClass=\
org.apache.activemq.book.ch7.spring.BrokerFactoryBeanExample \
-Dlog4j.configuration=file:src/main/java/log4j.properties \
-Dexec.args="src/main/resources/org/apache/activemq/book/ch7/spring-1.0.xml"
...
[INFO] [exec:java {execution: default-cli}]
Starting broker with the following configuration:
src/main/resources/org/apache/activemq/book/ch7/spring-1.0.xml
INFO | Using Persistence Adapter:
AMQPersistenceAdapter(data/localhost)
INFO | AMQStore starting using directory:
data/localhost
INFO | Kaha Store using data directory
data/localhost/kr-store/state
INFO | Active data files: []
INFO | ActiveMQ 5.4.1 JMS Message Broker (localhost) is starting
INFO | For help or more information please see:
http://activemq.apache.org/
INFO | Kaha Store using data directory
data/localhost/kr-store/data
INFO ManagementContext - JMX consoles can connect to
service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi
INFO | Listening for connections at: tcp://localhost:61616
INFO | Connector openwire Started
INFO |ActiveMQ JMS Message Broker
(localhost, ID:wfh-dejanb-65076-1269595139615-0:0) started
Sending: {price=22.74502068626, stock=JAVA, offer=22.767765706954,
up=true}
on destination: topic://STOCKS.JAVA
Sending: {price=65.23301909637, stock=IONA, offer=65.29825211547,
up=true}
on destination: topic://STOCKS.IONA
Sending: {price=65.09672311118, stock=IONA, offer=65.16181983429,
up=false}
on destination: topic://STOCKS.IONA
Sending: {price=64.84016157839, stock=IONA, offer=64.90500173997,
up=false}
on destination: topic://STOCKS.IONA
Sending: {price=22.560415476111, stock=JAVA, offer=22.582975891587,
up=false}
on destination: topic://STOCKS.JAVA
Sending: {price=64.43834994393, stock=IONA, offer=64.50278829387,
up=false}
on destination: topic://STOCKS.IONA
Sending: {price=22.583510723322, stock=JAVA, offer=22.606094234045,
up=true}
on destination: topic://STOCKS.JAVA
...

在表7.9中,你应该看到了代理通过Spring配置使用BrokerFactoryBean启动并且股票价格消息被发送到代理。
除了BrokerFactoryBean,你也能使用XBean with Spring。
使用Apache XBean with Spring
默认的,ActiveMQ为它的内部配置目的使用Spring和Apache XBean( http://mng.bz/EAfX)。所以我们在前面章节中用来配置许多特性的所有的activemq.xml文件基本上是由一个XBean定制XML格式支持的Spring配置文件。XBean提供了定义和使用定制的XML语法的能力,这种语法比基本的Spring语法更紧凑。虽然现在Spring提供了这么做的能力,但是当ActiveMQ被发明的时候这样的特性不可用(那时候Spring仅支持DTDs)。
下面的带啦显示了使用Spring和XBean的简单Java应用的示例:

Listing 7.10 The XBeanBroker class

package org.apache.activemq.book.ch7.xbean;
import org.apache.activemq.book.ch6.Publisher;
import org.apache.xbean.spring.context.FileSystemXmlApplicationContext;
public class XBeanBroker {
  public static void main(String[] args) throws Exception {
    if (args.length == 0) {
      System.err.println("Please define a configuration file!");
      return;
    }
    String config = args[0];
    System.out.println("Starting broker with the following configuration: " + config);
    System.setProperty("activemq.base",
    System.getProperty("user.dir"));
    FileSystemXmlApplicationContext
    context = new FileSystemXmlApplicationContext(config);
    Publisher publisher = new Publisher();
    for (int i = 0; i < 100; i++) {
      publisher.sendMessage(new String[]{"JAVA", "IONA"});
    }
  }
}

代码7.10接受一个参数作为XML配置文件的路径,设置了activemq.base系统属性,,并且使用XML配置文件实例化了一个Spring应用环境。然后publisher被实例化并被用来发送一个简单消息100次。这就是整个应用。其他的每件事都由ActiveMQ和Spring框架处理。请注意在这个示例中使用的application context是从XBean来的,不是Spring框架来的。这个示例能用下面的命令跑起来。

Listing 7.11 Start ActiveMQ Using XBean with Spring
$ mvn exec:java \
-Dexec.mainClass=org.apache.activemq.book.ch7.xbean.XBeanBroker \
-Dlog4j.configuration=file:src/main/java/log4j.properties \
-Dexec.args= \
"src/main/resources/org/apache/activemq/book/ch6/activemq-simple.xml"
...
[INFO] [exec:java {execution: default-cli}]
Starting broker with the following configuration:
src/main/resources/org/apache/activemq/book/ch6/activemq-simple.xml
INFO | Using Persistence Adapter:
AMQPersistenceAdapter(data/localhost)
INFO | AMQStore starting using directory: data/localhost
INFO | Kaha Store using data directory data/localhost/kr-store/state
INFO | Active data files: []
INFO | ActiveMQ 5.4.1 JMS Message Broker (localhost) is starting
INFO | For help or more information please see:
http://activemq.apache.org/
INFO | Kaha Store using data directory data/localhost/kr-store/data
INFO | JMX consoles can connect to
service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi
INFO | Listening for connections at: tcp://localhost:61616
INFO | Connector openwire Started
INFO | ActiveMQ JMS Message Broker
(localhost, ID:dejanb-65363-1269596340878-0:0) started
Sending: {price=53.794098159875, stock=IONA, offer=53.847892258035,
up=false}
on destination: topic://STOCKS.IONA
Sending: {price=53.489740886575, stock=IONA, offer=53.543230627461,
up=false}
on destination: topic://STOCKS.IONA
Sending: {price=53.5342708859, stock=IONA, offer=53.58780515680,
up=true}
on destination: topic://STOCKS.IONA
Sending: {price=53.86122035252, stock=IONA, offer=53.91508157288,
up=true}
on destination: topic://STOCKS.IONA
Sending: {price=54.15343454330, stock=IONA, offer=54.207587977851,
up=true}
on destination: topic://STOCKS.IONA
Sending: {price=49.27384513708, stock=JAVA, offer=49.323118982218,
up=false}
on destination: topic://STOCKS.JAVA
Sending: {price=53.83373859262, stock=IONA, offer=53.8875723312,
up=false}
on destination: topic://STOCKS.IONA
Sending: {price=53.933391780045, stock=IONA, offer=53.98732517182,
up=true}
on destination: topic://STOCKS.IONA
...
[i]
被启动的代理和先前定义的示例表现相同。
除了compact XBean提供的XML语法,Spring也支持XML namespace。
7.2.4使用定制的XML namespace with Spring
最近版本的所有Spring框架都允许开发者使用定制的XML格式。ActiveMQ提供了一个定制的XML schema来通过Spring配置文件配置ActiveMQ。下面的类表展示了如何通过XML namespace使用它的定制的Spring schema来配置ActiveMQ。
[i]
Listing 7.12 ActiveMQ XML configuration using Spring 2.x (and newer)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:amq="http://activemq.apache.org/schema/core"          ----Define URI and location of XSD
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd">  ----Define URI and location of XSD
<amq:broker brokerName="localhost" dataDirectory="${activemq.base}/data">
<amq:transportConnectors>
<amq:transportConnector name="openwire" uri="tcp://localhost:61616" />
</amq:transportConnectors>
<amq:plugins>
<amq:simpleAuthenticationPlugin>
<amq:users>
<amq:authenticationUser username="admin" password="password" groups="admins,publishers,consumers"/>
<amq:authenticationUser username="publisher" password="password" groups="publishers,consumers"/>
<amq:authenticationUser username="consumer" password="password" groups="consumers"/>
<amq:authenticationUser username="guest" password="password" groups="guests"/>
</amq:users>
</amq:simpleAuthenticationPlugin>
</amq:plugins>
</amq:broker>
</beans>

正如你在表7.12中所看到的,首先一个前缀被声明,它将在整个XML文档中用来从定制schema中引用元素类型。为ActiveMQ普遍使用的前缀是amq。第二个是在前缀右面的URI,在这个示例中它是 http://activemq.apache.org/schema/core。前缀用于引用从XML文档内而来的URI。第三,这个URI被用作一个标志通过schemaLocation属性来指向XML schema document(XSD)的实际位置。例如,当<amq:broker>元素被使用,amq前缀作为URI的前缀并且URI指向XSD,在那里代理元素能被找到的。
一旦XML namespace被声明了,我们能使用定制的XML语法自由地定义我们代理相关的beans。在这个特别的示例中我们如前面第六章示例中配置的配置了代理,使用简单的authentication插件。现在Spring代理能如下启动。

Listing 7.13 Start ActiveMQ using a configuration with a custom XML namespace
$ mvn -e exec:java \
-Dexec.mainClass=org.apache.activemq.book.ch7.spring.SpringBroker \
-Dlog4j.configuration=file:src/main/java/log4j.properties \
-Dexec.args=\
src/main/resources/org/apache/activemq/book/ch7/spring-2.0.xml
...
[INFO] [exec:java {execution: default-cli}]
Starting broker with the following configuration:
src/main/resources/org/apache/activemq/book/ch7/spring-2.0.xml
INFO | Using Persistence Adapter:
AMQPersistenceAdapter(${activemq.base}/data/localhost)
INFO | AMQStore starting using directory: data/localhost
INFO | Kaha Store using data directory data/localhost/kr-store/state
INFO | Active data files: []
INFO | ActiveMQ 5.4.1 JMS Message Broker (localhost) is starting
INFO | For help or more information please see: http://activemq.apache.org/
INFO | Kaha Store using data directory data/localhost/kr-store/data
INFO | JMX consoles can connect
to service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi
INFO | Listening for connections at: tcp://localhost:61616
INFO | Connector openwire Started
INFO | ActiveMQ JMS Message Broker
(localhost, ID:dejanb-65324-1269595874364-0:0) started
Sending: {price=83.53568740848, stock=IONA, offer=83.61922309589, up=true}
on destination: topic://STOCKS.IONA
Sending: {price=84.15670625187, stock=IONA, offer=84.24086295812, up=true}
on destination: topic://STOCKS.IONA
Sending: {price=83.64752134809, stock=IONA, offer=83.7311688694, up=false}
on destination: topic://STOCKS.IONA
Sending: {price=83.33023218494, stock=IONA, offer=83.41356241712, up=false}
on destination: topic://STOCKS.IONA
Sending: {price=84.05476877613, stock=IONA, offer=84.13882354490, up=true}
on destination: topic://STOCKS.IONA
Sending: {price=57.75764610250, stock=JAVA, offer=57.815403748606, up=true}
on destination: topic://STOCKS.JAVA
Sending: {price=84.3813034823, stock=IONA, offer=84.46568478585, up=true}
on destination: topic://STOCKS.IONA
Sending: {price=84.77874758495, stock=IONA, offer=84.86352633253, up=true}
on destination: topic://STOCKS.IONA
...

在表7.13中显示的示例使用了最普遍的类型的XML配置文件。所以虽然没有什么新东西,但是很多开发人员不能充分理解。
现在我们已经研究和演示了ActiveMQ许多风格的配置示例,是该改变一点方式来看看使用ActiveMQ的普遍方式:建立一个使用被称为request/reply的普遍的JMS paradigm的应用。

猜你喜欢

转载自flxchy4.iteye.com/blog/1741813
今日推荐