JMS
主要是解耦。提升效率
应用条件。不需要返回值。
主要的消息对象有四种
TextMessage
MapMessage
常用的两种。对象和流的不常用
active 8161 页面的简单介绍
主要的是
发布了多少消息
消费了多少消息
没消费多少消息
还有就是连接到这个队列的消费者数量。
demo
需要引入
activemq-client的依赖
其它相关依赖会自动导入
9步
1,创建连接工厂 这个是JMS定义的接口。
ActiveMQConnenctionFactory f= new ActiveMQConectionFactory("tcp://192.168.:61616);
2,通过工厂拿到连接
Connection c = f.createContection();
3,启动连接
c.start();
4,创建session 参数,是否开启事务。
Session s = c.createSession(false,Session.AUTOACKNOWLEDGE);
5,创建队列
Queue q = s.cresateQueue(“test”):
6,创建生产者对象。、
MessageProducer p = session.createProducer(q);
7,创建message对象。
TextMessage m = session.createTextMessage(“我来了”):
8,发送消息。首先是创建了队列,你是生产者,你有消息
p.send(m);
9,关闭资源。
p.close();
s.close();
c.close();
我们消费者
前5步都是一样的
6 ,创建消费者
MessageConsumer c= s.createConsumer(q);
7,创建监听
c.setMessageListener(new MessageListener(){
public void onMessage(Message arg0){
TextMessage m = (TextMessage)arg0;
sout(m.getText());
)
8,我们要程序停止。因为如果一直走,就会关闭资源了
System.in.read(); 让监听有效。
与spring整合
其实前5步都是一样的。可以用框架来处理。
主要是工厂
spring封装了一下。自己的工厂
然后是jmsTemplate 主要是自动生产session 和 producer
Message在 template的send方法中new一个匿名内部类。是spirng MessageCreater
用@Autowired注入的时候,因为是根据类型注入
入股有两个同种类型的,我们怎么处理呢
变量的名字必须是和bean的名字一样。
项目依赖必须启动,否则没有实现类的对象。
配置包扫描
1️⃣在spring的配置文件中我们需要一个bean
是工厂。propety brokerURL vlaue =tcp://
2️⃣在创建一个SingeConnectionFactory spring 的一个工厂
property 引用1️⃣
3️⃣创建JmsTemplate spring的 引用2️⃣
4️⃣ 创建bean ActiveMQQueue mq的 构造函数给一个name
@Component
public class MyPro {
@Autowired
private JmsTemplate jmsTemplate;
@Autowired
private Destination queueTextDestination;
public void send(final String text) {
jmsTemplate.send(queueTextDestination, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage(text);
}
});
}
}
import home.MyPro;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applications.xml")
public class Test {
@Autowired
private MyPro myPro;
@org.junit.Test
public void $1(){
myPro.send("p to p");
}
}
消息接受者的配置
因为不用接收消息了。所以不用配置JmsTemplate了 Spring的配置文件
我们需要配置监听器相关的东西了
首先要在java
中写一个监听器的类
然后
配置
<bean class = "org.springframework.jms.listener.DefaultMessageListenerContainer">
//关联3个属性。
<property name = "connectionfactory" ref="connectionfactory">
<property nmae= "destination" ref = "queueTextDestination">
<property nmae = "messageListener" ref ="myListener">
package home;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
public class MyLis implements MessageListener
{
public void onMessage(Message message) {
TextMessage mes = (TextMessage) message;
try {
System.out.println(mes.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
}
在spring的配置文件中我们已经把bean配置了。
package home;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.io.IOException;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:application.xml")
public class Test {
@org.junit.Test
public void $1() {
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
}
启动加载环境即可,但是需要等待输入。否则就退出了。自动监听
topic 只是把Destination的名字改一下即可
以上为demo
、
实际的应用中如果只需要处理一次,那么应该用queue。
实际中处理的步骤
第一:以前直接的依赖jar 删除
第二:由于第一部我们的代码会报错。因为无法找到对应的类。删除相关的信息
第三:引入 spring-jms以及activemq- client两个jar
第四:将demo中的spring配置导入。工厂啊,spring工厂啊,JmsTemplate , Destination
这个配置文件需要引入这个web工程,那么在web.xml中我们需要引入这个配置
<context-parm>
<param-name>contextConfigLoaction<param-name>
<param-value>classspath:spring-*.xml<param-vlaue>
在原来用rpc的地方,引入我们的Jmstemplate
我们在项目中引入jms
关键就是将之前方法的参数,直接用
JSON.toJSONString(list);直接转成字符串,因为,有对象,所以必须实现序列化。list 也需要是序列化的。所以用对象不行。
我们通过json转成string 这样是最简单的。
配置文件的引入主要就是改用一下队列的名称,增强可读性。
package home;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
import java.util.List;
@Component
public class MyServiceLis implements MessageListener{
@Autowired
private SearchService searchService;
public void onMessage(Message message) {
TextMessage mes = (TextMessage) message;
try {
String text = mes.getText();
List<Pojo> pojos = JSON.parseArray(text, Pojo.class);
searchService.importa(pojos);
} catch (JMSException e) {
e.printStackTrace();
}
}
}
如果是用服务器启动。我们就不需要读等待了。因为服务器没关。
项目中就是重写一下listener
主要是之前在rpc
的service
现在是本地了直接注入。通过mq得到消息,直接转换数据,直接调用了。
删除,在原有的基础上赋值一个queue改一个新的名字。
将bean中的 Destination 用@Autowired引入 ,JmsTemplate之前就引入过了
消费端,我们需要新的监听器,以及默认的监听容器。
但是静态页面生成是多台服务器上都有静态页面了。所以我们需要用到topic queue 就满足不了需求了
也就是tomcat和ngix 一起放在一台服务器上。
在配置文件中多一个topic的配置。
在java代码中因为我们用@Autowired ,所以是根据类型自动装配,因为我们建立了两个Destination
的对象。所以我们不需要和配置中的id 对应。否则要报错
然后在用JmsTemplate
来send, 因为是ids
我们遍历的发送 id+“”
这个项目可以不用dubbo了相应的jar dubbo的 zookeeper的以及 zkclient的jar都可以不要了
然后之前在spring配置文件中的dubbo的配置也可以不要了。直接走mq
Long.parseLong(String text);就是将queue换成了topic 其它都是一样的。多了一步将字符串转换的步骤。
new File(pagedir+goodsid+".html”).delete();这样就把本地的文件删除了。
是不是web工程,和main 或者是test
运行有很大区别。