7.1 Embedding ActiveMQ using Java

——用原生Java嵌入ActiveMQ

2016-06-07 11:34:12.0

7.1 使用纯Java嵌入ActiveMQ

    今天几乎所有的开发者都会使用一些框架去开发他们的应用,但最好的方式是使用原生的Java。在这部分中我们将通过ActiveMQ的JavaAPI来初始化和配置。你会看到除了使用Java代码外不用任何其他东西,如何通过使用BrokerService类来配置服务端。

    之后,我们将讲到如何通过自定义的xml文件来配置服务端。我们使用BrokerFactory类来完成这个目标,你会看到如何通过常规配置文件把ActiveMQ嵌入到你的应用当中。这部分之后,你就可以用任何一种配置在你的应用中嵌入ActiveMQ了。

7.1.1 使用BrokerService类嵌入ActiveMQ

    当使用原生的Java来启动服务端时,org.apache.activemq.broker.BrokerService类就是一个入口。该类用于配置服务端,并管理其完整的生命周期。演示BrokerService类的最好方式莫过于通过一个恰当的例子了。让我们通过第6章中的验证插件配置,来看看如何通过原生java代码来实现相同的功能。首先回顾下熟悉的xml配置是怎样的。

代码清单7.1 通过xml配置ActiveMQ使用安全插件
<broker xmlns="http://activemq.apache.org/schema/core"
    brokerName="myBroker" dataDirectory="${activemq.base}/data">
    <transportConnectors>
        <transportConnector name="openwire"
            uri="tcp://localhost:61616" />
    </transportConnectors>
    <plugins>
        <simpleAuthenticationPlugin>
            <users>
                <authenticationUser username="admin"
                    password="password" groups="admins,publishers,consumers" />
                <authenticationUser username="publisher"
                    password="password" groups="publishers,consumers" />
                <authenticationUser username="consumer"
                    password="password" groups="consumers" />
                <authenticationUser username="guest"
                    password="password" groups="guests" />
            </users>
        </simpleAuthenticationPlugin>
    </plugins>
</broker>

    代码清单7.1通过标准的Xml配置文件定义了一个指定名称和数据目录的服务端,并配置了传输连接器和一个插件。下面看一下,使用原生java代码怎样来达到相同的目的。

代码清单7.2 通过原生Java代码配置ActiveMQ使用安全插件
public static void main(String[] args) throws Exception {
	BrokerService broker = new BrokerService();
	broker.setBrokerName("myBroker");
	broker.setDataDirectory("data/");
	
	SimpleAuthenticationPlugin authentication = new SimpleAuthenticationPlugin();
	
	List<AuthenticationUser> users = new ArrayList<AuthenticationUser>();
	users.add(new AuthenticationUser("admin", "password", "admins,publishers,consumers"));
	users.add(new AuthenticationUser("publisher", "password", "publishers,consumers"));
	users.add(new AuthenticationUser("consumer", "password", "consumers"));
	users.add(new AuthenticationUser("guest", "password", "guests"));
	authentication.setUsers(users);
	
	broker.setPlugins(new BrokerPlugin[]{authentication});
	
	/*JaasAuthenticationPlugin jaas = new JaasAuthenticationPlugin();
	jaas.setConfiguration("src/main/resources/org/apache/activemq/book/ch5/login.config");
	broker.setPlugins(new BrokerPlugin[]{jaas});*/		
	
	broker.addConnector("tcp://localhost:61617");
	
	broker.start();
	
	System.out.println();
	System.out.println("Press any key to stop the broker");
	System.out.println();
	
	System.in.read();
}

    正如你看到的,代码清单7.2中,首先是实例化了BrokerService,然后设置了brokerName和dataDirectory两个属性。之后,通过setPlugins()方法将SimpleAuthenticationPlugin设置到BrokerSerivce实例中,之后又通过addConnector()方式将一个传输连接器添加到实例中。最后通过start()方法启动服务端。现在你的服务端已经通过原生的Java代码完全初始化好了,我们没有使用任何xml配置文件。通过下面的命令运行代码,观察代码的运行效果:

清单7.3 运行使用BrokerService类的纯Java代码示例
 INFO | Using Persistence Adapter: KahaDBPersistenceAdapter[D:\wisest\Development\coding\activemqlearn\activemq-data\localhost\KahaDB]
 INFO | JMX consoles can connect to service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi
 INFO | KahaDB is version 6
 INFO | Recovering from the journal @1:5497
 INFO | Recovery replayed 10 operations from the journal in 0.015 seconds.
 INFO | PListStore:[D:\wisest\Development\coding\activemqlearn\activemq-data\localhost\tmp_storage] started
 INFO | Apache ActiveMQ 5.13.2 (myBroker, ID:xuyh-PC-51966-1465278116888-0:1) is starting
 INFO | Listening for connections at: tcp://127.0.0.1:61617
 INFO | Connector tcp://127.0.0.1:61617 started
 INFO | Apache ActiveMQ 5.13.2 (myBroker, ID:xuyh-PC-51966-1465278116888-0:1) started
 INFO | For help or more information please see: http://activemq.apache.org
 WARN | Store limit is 102400 mb (current store usage is 0 mb). The data directory: D:\wisest\Development\coding\activemqlearn\activemq-data\localhost\KahaDB only has 14274 mb of usable space. - resetting to maximum available disk space: 14274 mb
 WARN | Temporary Store limit is 51200 mb (current store usage is 0 mb). The data directory: D:\wisest\Development\coding\activemqlearn\activemq-data\localhost only has 14274 mb of usable space. - resetting to maximum available disk space: 14274 mb

Press any key to stop the broker

    注意,关于代码清单7.3,有一点非常重要,插件一定要添加在连接器之前,否则插件将不能被初始化;想相似地,在服务端启动之后添加连接器,服务端也不会正确的启动。

    当你想用原生Java代码来配置服务端时,BrokerService类是非常有用的。在那些你不需要外部的个性化配置的场合,这种方式都是有用的。然而在有些情况下,你可能要用同一个ActiveMQ标准的配置文件,去配置多个ActiveMQ服务端应用。为了做到这一点,我们要使用org.apache.activemq.broker.BrokerFactory。

7.1.2 用BrokerFactory嵌入ActiveMQ

    BrokerFactory是一个工具类,它可以是通过ActiveMQ URL创建服务端实例变得更为简单。基于broker URL模式,BrokerFactory类定位到适当的工厂并用以创建一个BrokerService类的实例。使用最为广泛的工厂类是XBeanBrokerFactory,可以通过简单的XBean样式的URI类配置。下面是一个XBean样式的URI示例:xbean:/path/to/activemq.xml

    示例中的URI告诉BrokerFactory使用XBeanBrokerFactory,并且使用冒号后面的路径类创建服务端。

    现在让我们看一下下面的代码清单,用BrokerFactory类读取标准的ActiveMQ的XML配置文件来创建BrokerService实例:

清单7.4 使用BrokerFactory与XML配置文件
public static void main(String[] args) throws Exception {
    System.setProperty("activemq.base", System.getProperty("user.dir"));
    BrokerService broker = BrokerFactory.createBroker(
            new URI("xbean:target/classes/org/apache/activemq/book/ch7/activemq-simple.xml"));
    broker.start();

    System.out.println();
    System.out.println("Press any key to stop the broker");
    System.out.println();

    System.in.read();
}

    注:示例中使用的配置文件如下:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:amq="http://activemq.apache.org/schema/core"
	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
  http://activemq.apache.org/camel/schema/spring http://activemq.apache.org/camel/schema/spring/camel-spring.xsd">

	<!-- Allows us to use system properties as variables in this configuration file -->
	<bean
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />

	<broker xmlns="http://activemq.apache.org/schema/core"
		brokerName="localhost" dataDirectory="${activemq.base}/data">

        <plugins>
            <simpleAuthenticationPlugin>
                <users>
                    <authenticationUser username="admin" password="password" groups="admins,publishers,consumers"/>
                    <authenticationUser username="publisher" password="password" groups="publishers,consumers"/>
                    <authenticationUser username="consumer" password="password" groups="consumers"/>
                    <authenticationUser username="guest" password="password" groups="guests"/>
                </users>
            </simpleAuthenticationPlugin>
        </plugins>
        
		<!-- The transport connectors ActiveMQ will listen to -->
		<transportConnectors>
			<transportConnector name="openwire"
				uri="tcp://localhost:61617" />
		</transportConnectors>
	</broker>

</beans>

    正如你在清单7.4中看到的,BrokerFactory.createBroker()方法使用了一个配置URI来创建BrokerService实例。注意清单7.4中使用的URI,是xbean模式,这告诉服务端工厂查找路径中指定的配置文件。为了真实实践一下其运行,下面的清单演示了运行方法:

清单7.5 运行BrokerFactory实例
$ mvn exec:java \
-Dexec.mainClass=org.apache.activemq.book.ch7.broker.Factory \
-Dlog4j.configuration=file:src/main/java/log4j.properties
...
[INFO] [exec:java {execution: default-cli}]
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 | Listening for connections at: tcp://localhost:61616
INFO | Connector openwire Started
INFO | ActiveMQ JMS Message Broker
(localhost, ID:dejanb-65001-1269594442403-0:0) started
Press any key to stop the broker
...

    你也可以使用 broker:模式,简单完整的通过配置URI来配置,看下下面的URI:

broker:(tcp://localhost:61616,network:static:tcp://remotehost:61616)
?persistent=false&useJmx=true

    该URI包含了启动服务端足够的配置信息,包含了网络和传输连接器,禁用了持久化,显示地启动了JMX。可以从ActiveMQ官网获得更详细的关于URI的资料(http://mng.bz/FNos)。

    就像一早提到的,很多开发者使用一些框架来完成他们的开发任务,由于Spring(http://www.springframework.org/)是当今使用最为广泛的框架,因此让我们看下,在Spring中,ActiveMQ作为一个组件,如何使用和配置。