spring+activemq配置一个项目同时连接两个activemq服务器

公司项目中需要与多个平台交互信息,采用activemq。与数据采集平台连接用的是一个activemq,与上级平台连接用的是另一个activemq,也就是要连接到上级平台的activemq。我们的项目是可以同时部署为上级平台或者下级平台,下级平台往上级平台发送报表的时候要发送到上级平台的activemq,下级平台接收数据采集器的数据的时候要发送任务信息到自身的activemq。自身的activemq按照正常的配置,不再细写,参考:https://www.cnblogs.com/jaycekon/p/ActiveMq.html

问题是现在要怎么再配置一个连接池到上级平台的activemq。我的做法是新建一个类,类名随便起了个,就叫ActiveMQFactory,在这个类里面有2个方法,一个获得缓存连接工厂,一个获得JmsTemplate。代码如下:

package com.infinova.oms.activemq;

import javax.jms.ConnectionFactory;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.jms.core.JmsTemplate;

public class ActiveMQFactory {
	
	String username;
	
	String password;
	
	String brokenUrl;
	
	long receiveTimeout;
	
	String destinationName;
	
	boolean pubSubDomain;
	
	private int sessionCacheSize;
	
	private CachingConnectionFactory  connection;
	
	private JmsTemplate jmsTemplate;
	
	public ConnectionFactory getConnection() {
		if(connection == null) {
			connection = new CachingConnectionFactory(new ActiveMQConnectionFactory(username,password,brokenUrl));
			connection.setSessionCacheSize(sessionCacheSize);
		}
		return connection;
	}
	
	public JmsTemplate getJmsTemplate(){
		if(jmsTemplate == null) {
			jmsTemplate = new JmsTemplate(getConnection());
			jmsTemplate.setReceiveTimeout(receiveTimeout);
			jmsTemplate.setDefaultDestinationName(destinationName);
			jmsTemplate.setPubSubDomain(pubSubDomain);
		}
		return jmsTemplate;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getBrokenUrl() {
		return brokenUrl;
	}

	public void setBrokenUrl(String brokenUrl) {
		this.brokenUrl = brokenUrl;
	}

	public long getReceiveTimeout() {
		return receiveTimeout;
	}

	public void setReceiveTimeout(long receiveTimeout) {
		this.receiveTimeout = receiveTimeout;
	}

	public String getDestinationName() {
		return destinationName;
	}

	public void setDestinationName(String destinationName) {
		this.destinationName = destinationName;
	}

	public boolean isPubSubDomain() {
		return pubSubDomain;
	}

	public void setPubSubDomain(boolean pubSubDomain) {
		this.pubSubDomain = pubSubDomain;
	}

	public int getSessionCacheSize() {
		return sessionCacheSize;
	}

	public void setSessionCacheSize(int sessionCacheSize) {
		this.sessionCacheSize = sessionCacheSize;
	}
	

}

然后在spring的配置文件上配置这个bean,配置如下:


    	
    	
    	
        
        
        
        
    

至此,发送消息到另一个指定的activemq服务器的初始工作就做好了,接下来就是调用的问题,新建一个Spring Controller,将上面的bean自动装配进去,调用这个对象的getJmsTemplate()方法得到jmsTemplate对象,就可以用jmsTemplate发送消息,要进一步封装自己看需要关键代码如下:

public class MessageController {

    @Autowired
    private ActiveMQFactory activemqFactory;

    @RequestMapping(value = "/sendMessage", method = RequestMethod.GET)
    @ResponseBody
    public String send() {
        activemqFactory.getJmsTemplate().send(new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                return session.createTextMessage("Hello World");
            }
        });
        return "success";
    }

以上是实现发送的步骤。需求是下级要向上级发送报表,但上级下级其实是同一套程序,那项目很可能要作为上级接收来自下级的报表数据,这时候就要监听器了。按照上面文章的例子,监听器的配置首先要配置一个监听器容器,然后往这个容器里面加监听器。

 
    

    
    
        
        
        
    

但是这里在配置监听器容器的时候,需要传入一个连接工厂对象,但我上面新建的ActiveMQFactory类并不是连接工厂对象啊,只是一个类似代理类一样的东西,能够获得连接工厂对象和jmsTemplate对象而已(其实这里可以集成连接工厂的子类CachingConnectionFactory,然后配置为一个bean,将该bean传进去)。但这里我用了另外一种思路:监听器容器不就是要一个连接工厂吗,一个目的地吗,那好,我继承你这个DefaultMessageListenerContainer,然后我在构造函数里设置连接工厂,设置的连接工厂怎么来,通过ActiveMQFactory对象获得,在自定义的继承类声明一个ActiveMQFactory对象注入进来。继承的监听器容器类代码如下:

package com.infinova.oms.activemq;

import org.apache.activemq.command.ActiveMQQueue;
import org.springframework.jms.listener.DefaultMessageListenerContainer;

public class ActiveMQListenerContainer extends DefaultMessageListenerContainer {
	
	public ActiveMQListenerContainer(String destinationName,ActiveMQFactory activemqFactory){
		this.setConnectionFactory(activemqFactory.getConnection());
		this.setDestination(new ActiveMQQueue(destinationName));
	}
	
	public ActiveMQListenerContainer() {
		
	}
}

这里我是传入一个activemqFactory对象和目的地名称作为构造参数,根据目的地名称创建目的地设置父类的setDestination方法。创建了监听器容器之后,再创建监听器类,代码如下:

package com.infinova.oms.activemq;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

public class ActiveMQMessageListener implements MessageListener {

	public void onMessage(Message message) {
		TextMessage tm = (TextMessage) message;
        try {
            System.out.println("ActiveMQMessageListener监听到了文本消息:\t\n"
                    + tm.getText());
        } catch (JMSException e) {
            e.printStackTrace();
        }
	}

}

之后就是配置到spring上了,配置如下:


    

    
    
         
         
       	  
    

项目启动后,发送消息就能监听到了。


你可能感兴趣的:(消息队列)