Java Message Queuing-spring integration ACTIVEMQ

Source: Internet
Author: User

1. Overview

First, let's review the Java Messaging Service, in my previous blog, "Java Message Queuing-JMS Overview", I analyzed for you:

    1. Messaging Service: A middleware that solves the coupling between two live multiple programs, with Java implementation at the bottom.
    2. Advantages: Asynchronous, reliable
    3. Message model: Point-to-point, publish/Subscribe
    4. Objects in JMS

Then in another blog "Java Message Queuing-activemq combat", and everyone from 0 to 1 to open a ACTIVEMQ project, in the process of project development, we have a certain understanding of ACTIVEMQ:

    1. Multiple languages and protocols for writing clients. Languages: Java, C, C + +, C #, Ruby, Perl, Python, PHP. Application protocol: Openwire,stomp REST,WS NOTIFICATION,XMPP,AMQP
    2. Full support for JMS1.1 and the Java EE 1.4 specification (persistence, XA messages, transactions)
    3. With spring support, ACTIVEMQ can easily be embedded into a system that uses spring, and also supports Spring2.0 features
    4. Tested by common Java EE servers (such as Geronimo,jboss 4, glassfish,weblogic), where the configuration of the JCA 1.5 resource adaptors allows ACTIVEMQ to automatically deploy to any compatible Java EE 1.4 On commercial Server
    5. Supports multiple transfer protocols: In-vm,tcp,ssl,nio,udp,jgroups,jxta
    6. Support for high-speed message persistence through JDBC and journal
    7. Designed to ensure high-performance clustering, client-server, point-to-point
    8. Support Ajax
    9. Support for integration with axis
    10. It is easy to call the embedded JMS provider for testing

In the next blog post, I will be working with you to integrate spring and ActiveMQ, this blog post, we have implemented point-to-point asynchronous queue messages and pub/sub based on Spring+jms+activemq+tomcat (Publish/ Subscription) model, simple instance, does not contain any business.

2. Directory structure

2.1 Project Directory

The IDE chooses idea (recommended), and to avoid the hassle of downloading jars, the underlying uses MAVEN to build a project that integrates spring and ACTIVEMQ

   

   

2.2 Pom.xmlView Code

Because the Pom.xml file here is a bit long, it does not unfold.

We can see the fact that there are a few dependencies, 1, Spring Core relies on 2, ActiveMq core and pool (here if the students choose to import the jar, you can directly import our last blog said that the Activemq-all this jar package) 3, Java Servlet related dependencies

In this case, the dependent version of the ACTIVEMQ pool that we choose will be related to the subsequent DTD, need the version corresponding, so the students wait for the configuration of the Activemq file, you need to pay attention to the DTD version selection

2.3 Web

Web. XML is similar, specifying spring configuration file, SPRINGMVC naming, encoding format

<?xml version= "1.0" encoding= "UTF-8"? ><web-app xmlns= "Http://java.sun.com/xml/ns/javaee" xmlns:xsi= "http: Www.w3.org/2001/XMLSchema-instance "xsi:schemalocation=" Http://java.sun.com/xml/ns/javaee http://java.s Un.com/xml/ns/javaee/web-app_3_0.xsd "version=" 3.0 "> <display-name>archetype Created Web application< /display-name> <!--loading spring configuration files, such as Hibernate, JMS, etc.--<context-param> <param-name>    Contextconfiglocation</param-name> <param-value> Classpath:applicationcontext*.xml; </param-value> </context-param> <listener> <listener-class>    Org.springframework.web.context.contextloaderlistener</listener-class> </listener> <servlet> <servlet-name>springMVC</servlet-name> <servlet-class> Org.springframework.web.servlet.dispatcherservlet</servlet-class> <init-param> <param-name> Contextconfiglocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <lo ad-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc </servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!--working with encoded formats-&LT;FI Lter> <filter-name>characterEncodingFilter</filter-name> <filter-class> Org.springframework.web.filter.characterencodingfilter</filter-class> <init-param> <param-name >encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param > <param-name>forceEncoding</param-name> <param-value>true</param-value> </init -param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> & Lt;url-pattern>/*</url-pattern> </filter-mapPing></web-app> 

2.4 Springmvc and Applicationcontext.xml

There is nothing special in this springmvc, there is a need for students to refer to:

View Code

Applicationcontext.xml is primarily used to load beans, and there is no particular Java bean in our project, so it is used only to indicate the packet scan path:

View Code

2.5 applicationcontext-activemq.xml
<?xml version= "1.0" encoding= "UTF-8"? ><beans xmlns= "Http://www.springframework.org/schema/beans" xmlns: Xsi= "Http://www.w3.org/2001/XMLSchema-instance" xmlns:amq= "Http://activemq.apache.org/schema/core" xmlns:jms= " HTTP://WWW.SPRINGFRAMEWORK.ORG/SCHEMA/JMS "xmlns:context=" Http://www.springframework.org/schema/context "xmlns" : mvc= "Http://www.springframework.org/schema/mvc" xsi:schemalocation= "http://www.springframework.org/schema/b EANs http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/ Context Http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/ SCHEMA/MVC http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd Http://www.springframework.org/schem        A/JMS http://www.springframework.org/schema/jms/spring-jms-4.1.xsd Http://activemq.apache.org/schema/core Http://activemq.apache.Org/schema/core/activemq-core-5.12.1.xsd "> <context:component-scan base-package=" com.                           Jayce "/> <mvc:annotation-driven/> <amq:connectionfactory id=" Amqconnectionfactory " Brokerurl= "tcp://192.168.148.128:61616" username= "admin" passwo rd= "admin"/> <!--Configure JMS connection Foreman--<bean id= "ConnectionFactory" class= "org.springframework.jms.co Nnection. Cachingconnectionfactory "> <constructor-arg ref=" amqconnectionfactory "/> <property name=" Sessio Ncachesize "value="/> </bean> <!--define Message Queuing (queue)--<bean id= "Demoqueuedestination" class            = "Org.apache.activemq.command.ActiveMQQueue" > <!--Set the name of the message queue--<constructor-arg> <value>Jaycekon</value> </constructor-arg> </bean> <!--Configuring the JMS template (Queue), Spring provides a J The MS Tool class, which sends and receives messages. --<bean id= "JmstEmplate "class=" org.springframework.jms.core.JmsTemplate "> <property name=" connectionfactory "ref=" Connectio Nfactory "/> <property name=" defaultdestination "ref=" demoqueuedestination "/> <property name=" R Eceivetimeout "value=" 10000 "/> <!--true is Topic,false is the queue, the default is False, here the display writes out false--<property N Ame= "Pubsubdomain" value= "false"/> </bean> <!--Configure Message Queuing Listener (queue)---<bean id= "Queuemessagelis Tener "class=" com. Jayce.Filter.QueueMessageListener "/> <!--display inject message listener (Queue), configure connection factory, listener is the target of demoqueuedestination, listener is the listener defined above --<bean id= "Queuelistenercontainer" class= "Org.springframework.jms.listener.DefaultMessageListenerCont Ainer "> <property name=" connectionfactory "ref=" ConnectionFactory "/> <property name=" Destinatio N "ref=" demoqueuedestination "/> <property name=" MessageListener "ref=" Queuemessagelistener "/> </be An></bEans> 

Here and you explain this configuration file, if you can read from the above configuration file, you can skip. Students can also be viewed in the ACTIVEMQ official website.

1, ActiveMq in the DTD, before we declare the relevant configuration, we need to import the DTD in ActiveMq, or spring does not understand what our tags mean.

Http://activemq.apache.org/schema/core/activemq-core-5.12.1.xsd

We have configured the version of ACTIVEMQ in the Pom.xml file to rely on our version, like the dependent version, or we cannot find the relevant DTD

2.amq:connectionfactory: A straightforward configuration item that configures the address and username password for our link factory, where you need to be aware of choosing a TCP connection instead of an HTTP connection

3,jmstemplate: A more important configuration, here specify the connection factory, the default message to send the destination, as well as the length of the connection, the way to publish the message

3. Project Structure 3.1 Producerservice
Package com. Jayce.service;import Org.springframework.jms.core.jmstemplate;import Org.springframework.jms.core.MessageCreator ; import Org.springframework.stereotype.service;import Javax.annotation.resource;import javax.jms.Destination; Import Javax.jms.jmsexception;import javax.jms.message;import javax.jms.session;/** * Created by Administrator on 2017/ 1/5.    */@Servicepublic class Producerservice {@Resource (name= "jmstemplate") private jmstemplate jmstemplate; public void SendMessage (Destination destination,final String msg) {System.out.println (Thread.CurrentThread (). Getnam        E () + "send Message---------------------->" To Queue "+destination.tostring () +" +msg); Jmstemplate.send (Destination, new Messagecreator () {public Message CreateMessage (session session) throws Jmsex            ception {return session.createtextmessage (msg);    }        }); public void SendMessage (final string msg) {String destination = Jmstemplate.getdefaultdestinationname ();        System.out.println (Thread.CurrentThread (). GetName () + "Send message to queue" +destination+ "---------------------->" +msg);                Jmstemplate.send (New Messagecreator () {public Message CreateMessage (session session) throws JMSException {            return Session.createtextmessage (msg);    }        }); }}

The message producer is made into a service, and when we need to send a message, we only need to invoke the SendMessage method in the Producerservice instance to send a message to the default destination.

Here are two sending methods, one for sending to the default destination, and one for sending messages based on the destination.

Interested students can and my previous article, "Activemq combat" in the way ACTIVEMQ send messages in contrast, you can find some differences.

3.2 Consumerservice
Package com. Jayce.service;import Org.springframework.jms.core.jmstemplate;import Org.springframework.stereotype.Service; Import Javax.annotation.resource;import Javax.jms.destination;import Javax.jms.jmsexception;import javax.jms.textmessage;/** * Created by Administrator on 2017/1/5. */@Servicepublic class Consumerservice {    @Resource (name= "Jmstemplate")    private jmstemplate jmstemplate;    Public TextMessage receive (Destination Destination) {        TextMessage textmessage = (textmessage) jmstemplate.receive ( destination);        try{            System.out.println ("from queue" + destination.tostring () + "received message: \ t"                    + textmessage.gettext ())        } catch ( JMSException e) {            e.printstacktrace ();        }        return textmessage;}    }

Because we do not have any business in the project, so the processing of the message is also printed output. We just need to call the Receive method in Jmstemplate to get a message from the inside.

In contrast to our previous blog post, in the previous blog, we had to manually confirm the transaction after receiving the information so that ACTIVEMQ would be sure that the message had been read correctly. When spring is integrated, the transaction is managed by spring.

3.3 Messagecontroller
Package com. Jayce.controller;import com. Jayce.service.consumerservice;import com. Jayce.service.producerservice;import Org.slf4j.logger;import Org.slf4j.loggerfactory;import Org.springframework.stereotype.controller;import Org.springframework.web.bind.annotation.requestmapping;import Org.springframework.web.bind.annotation.requestmethod;import Org.springframework.web.bind.annotation.responsebody;import Javax.annotation.resource;import Javax.jms.destination;import javax.jms.textmessage;/** * Created by Administrator on 2017/1/5. */@Controllerpublic class Messagecontroller {private Logger Logger = Loggerfactory.getlogger (Messagecontroller.class)    ;    @Resource (name = "Demoqueuedestination") private Destination Destination;    Queue message producer @Resource (name = "Producerservice") private producerservice producer;    Queue message Consumer @Resource (name = "Consumerservice") private consumerservice consumer; @RequestMapping (value = "/sendmessage", method = Requestmethod.post) @ResponseBoDy public void Send (String msg) {Logger.info (Thread.CurrentThread (). GetName () + "------------Send to JMS Start");        Producer.sendmessage (msg);    Logger.info (Thread.CurrentThread (). GetName () + "------------Send to JMS End");        } @RequestMapping (value= "/receivemessage", method = Requestmethod.get) @ResponseBody public Object receive () {        Logger.info (Thread.CurrentThread (). GetName () + "------------receive from JMS Start");        TextMessage TM = consumer.receive (destination);        Logger.info (Thread.CurrentThread (). GetName () + "------------receive from JMS End");    return TM; }}

The control layer needs to be injected into our producers and consumers (in real development, producers and consumers will certainly not be in the same project, otherwise the message service is meaningless).

Now the service layer and the control layer are all right, and then we'll do a simple test

4. Project Test 4.1 start ACTIVEMQ

Make sure your ACTIVEMQ service is turned on.

    

4.2 Starting the Project

The project uses the Tomcat plug-in, avoids the trouble of downloading Tomcat locally, and students who need it can use it.

<plugins>      <plugin>        <groupId>org.apache.tomcat.maven</groupId>        < artifactid>tomcat7-maven-plugin</artifactid>        <configuration>          <port>8080</port >          <path>/</path>        </configuration>      </plugin></plugins>

4.3 Sending messages

Here's a plugin for Chrome PostMan Interested students can find out, in the Chrome extension program can be found, to avoid the back end of the classmate to get the page!

    

After we send a POST request, we look at the effect of the server:

As we can see, a message has been sent to the queue. Let's take a look at the current state of ACTIVEMQ:

As we can see, a message has been successfully sent to ACTIVEMQ.

4.4 Receiving messages

To access the server background using GET requests:

  

Output of the service:

ACTIVEMQ Server Status:

We can see that consumers have consumed a piece of information and have not broken the link with activemq.

  

4.5 Listeners

In the actual project, we seldom get the message manually, if we need to get the message manually, there is no need to use the ACTIVEMQ, you can use a redis is enough.

Cannot get the message manually, then we can choose to use a listener to listen for a message arrives, this can quickly complete the processing of the message.

4.5.1 Applicationcontext-activemq.xml Configuration

In the above configuration file, we have added this listener's configuration file by default, if the students do not want to use this listener, can be directly commented out.

    <!--Configure Message Queuing Listener (queue)--    <bean id= "queuemessagelistener" class= "com. Jayce.Filter.QueueMessageListener "/>    <!--display inject message listener (Queue), configure the connection factory, the target of monitoring is demoqueuedestination, The listener is the listener defined above--    <bean id= "Queuelistenercontainer"          class= " Org.springframework.jms.listener.DefaultMessageListenerContainer ">        <property name=" ConnectionFactory " ref= "ConnectionFactory"/>        <property name= "Destination" ref= "Demoqueuedestination"/>        < Property Name= "MessageListener" ref= "Queuemessagelistener"/>    </bean>

 

4.5.2 MessageListener

We need to create a class to implement the MessageListener interface:

Package com. Jayce.filter;import Javax.jms.jmsexception;import Javax.jms.message;import Javax.jms.messagelistener;import javax.jms.textmessage;/** * Created by Administrator on 2017/1/5. */public class Queuemessagelistener implements MessageListener {public    void onMessage (Message message) {        TextMessage TM = (textmessage) message;        try {            System.out.println ("Queuemessagelistener heard a text message: \ t"                    + tm.gettext ());            Do something ...        } catch (JMSException e) {            e.printstacktrace ();}}    }

The implementation of the OnMessage method of the interface, we will need to solve the business operations inside, this way, the completion of our producer-middleware-consumer, such a decoupled operation.

4.5.3 Test

As above, using postman to send a POST request, we can see inside the console that the message will print out immediately:

   

Then look at the status of the ACTIVEMQ server:

As we can see, the effect of using the listener is the same as the effect of receiving the message manually.

As a whole project, we have successfully integrated spring and ACTIVEMQ.

4.6 Pressure test

In fact, this is not a stress test, in the configuration of the Pom.xml file, we have seen a commons-httpclient dependence, and then we use httpclient constantly want to send messages to the server to see how fast the server to resolve the message:

Package com. Jaycekon.test;import Org.apache.commons.httpclient.httpclient;import Org.apache.commons.httpclient.methods.postmethod;import Org.junit.test;import Java.io.IOException;import java.util.concurrent.atomic.atomicinteger;/** * Created by Administrator on 2017/1/5.        */public class Client {@Test public void Test () {HttpClient HttpClient = new HttpClient ();    New Thread (New Sender (HttpClient)). Start ();    }}class Sender implements Runnable {public static Atomicinteger count = new Atomicinteger (0);    HttpClient HttpClient;    Public Sender (HttpClient client) {HttpClient = client; public void Run () {try {System.out.println (Thread.CurrentThread (). GetName () + "---Send mess                age-"+count.getandincrement ());                Postmethod post = new Postmethod ("Http://127.0.0.1:8080/SendMessage");                Post.addparameter ("msg", "Hello world!");                Httpclient.executemethod (POST); System.out.println (Thread.CurrentThread (). GetName () + "---Send message success-" +count.getandincrement ());            } catch (IOException e) {e.printstacktrace (); }        }    }

Here with HttpClient to send a POST request to the server, and then count the output, interested students can test their own, you can open a few threads, here only open a thread.

Java Message Queuing-spring integration ACTIVEMQ

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.