activemq简单的实现运用并不难。
发送端,消费者端,按步骤创建所需的属性。
发送端:
1.先创建连接工厂ConnectionFactory,这里有三个参数,分别是username,password和url//用failover:(url)?timeout=3000的方式更佳
2.通过连接工厂创建连接Connection,再connection.start启动这个连接
3.创建会话Session,通过connection创建:Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
4.消息目的地和生产者,都由会话Session创建:
//创建目的地,确立队列名称,这里用topic模式
Destination destination = session.createTopic(topicname);
//创建生产者,发送目的地传入
MessageProducer messageProducer = session.createProducer(destination);
5.发送消息,发送完成后将session进行commit
6.connection.close
消费端大同小异;
再聊聊消费端的监听方法。
我们可以自己创建一个listener继承MessageListener
消费端就能再创建完消费者后messageConsumer.setMessageListener(new Mylistener());对消息进行监听。
activemq大概有5中消息类型发送方式
TextMessage,ObjectMessage,BytesMessage,MapMessage和StreamMessage
目前接触到的以TextMessage和BytesMessage为主
TextMessage不必多说,存放的就是String类型的数据,几乎不用多做处理。
而BytesMessage接受到的类型为byte数组,接受到数据后还需要根据实际情况依据手头的协议对其进行解析。较为复杂。
说一个现在碰到的问题,就是在监听器中对业务逻辑进行处理难免使得程序臃肿,并且耦合度很高,不够优雅。
紧接着便是监听器的坑了。
在监听器内,由于监听器通常是由Servlet进行管理的,而程序中可能会用到各种由Spring管理的bean。由于二者在程序开始执行时加载的次序不同,前者先于后者,于是Spring管理的bean在监听器内是难以注入的。菜鸟也想飞的博客中指出,注解的方式执行的位置,spring的注入是在filter和listener之后的,(顺序是这样的listener >> filter >> servlet >> spring )。如果如果在监听器中有需要对容器中bean进行引用,就不能采用注解的方式了。只能手动的进行配置文件的读取。那么在这里就需要我们手动创建一个SpringContextHolder类,该类继承ApplicationContextAware接口。
@Component
public class SpringContextHolderimplements ApplicationContextAware {
private static ApplicationContextapplicationContext;
/**
* 实现ApplicationContextAware接口的context注入函数, 将其存入静态变量.
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
SpringContextHolder.applicationContext = applicationContext; // NOSONAR
}
/**
* 取得存储在静态变量中的ApplicationContext.
*/
public static ApplicationContextgetApplicationContext() {
checkApplicationContext();
return applicationContext;
}
/**
* 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
*/
@SuppressWarnings("unchecked")
public static T getBean(String name) {
checkApplicationContext();
return (T)applicationContext.getBean(name);
}
/**
* 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型.
*/
@SuppressWarnings("unchecked")
public static T getBean(Class clazz) {
checkApplicationContext();
return (T)applicationContext.getBeansOfType(clazz);
}
/**
* 清除applicationContext静态变量.
*/
public static void cleanApplicationContext() {
applicationContext =null;
}
private static void checkApplicationContext() {
if (applicationContext ==null) {
throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder");
}
}
}
最后通过这个类可以手动获得bean,在监听器内也就能用了。
网友评论