We all know that it is impossible to complete everything in one method to complete a module. It is necessary to divide and refine the code according to various dimensions to ensure the loose coupling of the system. For example, the template pattern in the design pattern reflects this, since it is Independent modules, then you need to call the methods of other classes or interfaces to complete what you need to do.
Figure 1:
The above picture shows that the method of one class needs to call the method called call in another class, and it is very simple to receive the return result, because they are both in the same process space, and both classes are the same Java virtual machine instance and both help us parse it. , just call it. But what if it's not in the same process space? Can we still achieve the effect we want? Obviously not.
Figure 2:
Because the two classes are in different process spaces, we can't call them as easily as before, so what should we do? Many people may think of the popular microservices. Indeed, microservices can perfectly solve the problem of distributing cross-process services in different applications.
In today's Internet-dominated environment, distributed systems have been widely accepted and used, various distributed architectures are emerging one after another, and technologies supporting various microservices and SOA architectures have emerged as the times require. From the original Spring Cloud to the popular Alibaba open source framework Dubbo, it clearly illustrates the importance of distributed systems.
But what I want to say now is not a distributed service framework, but a message service component - RabbitMQ
The above problems can also be solved through the message component method. Let me combine an example to illustrate how to use rabbitMq. It is an entry, haha.
Go directly to the code to solve all problems-_-
Import the required maven dependencies, and by the way, the spring and junit packages are also introduced to run the unit test
pom.xml
<properties>
<spring.version>3.2.8.RELEASE</spring.version>
<logback.version>1.1.5</logback.version>
<tomcat.version>7.0.81</tomcat.version>
</properties>
<dependencies>
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>4.0.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.24</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.0.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>${tomcat.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
</dependencies>
Because it is integrated with spring, rabbitmq.xml is introduced
<?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:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<rabbit:connection-factory id="connectionFactory" username="test" password="test" host="192.168.xxx.xxx" port="5672"/>
<rabbit:template id="programTemplate" connection-factory="connectionFactory" exchange="program.direct.exchange"/>
<rabbit:admin connection-factory="connectionFactory"/>
<rabbit:queue name="program.erland.queue" durable="true" auto-delete="false" exclusive="false">
<rabbit:queue-arguments>
<entry key="x-message-ttl">
<value type="java.lang.Long">60000</value>
</entry>
</rabbit:queue-arguments>
</rabbit:queue>
<rabbit:queue name="program.java.queue" durable="true" auto-delete="false" exclusive="false">
</rabbit:queue>
<rabbit:direct-exchange name="program.direct.exchange" durable="true" auto-delete="false">
<rabbit:bindings>
<rabbit:binding queue="program.erland.queue" key="erland"></rabbit:binding>
<rabbit:binding queue="program.java.queue" key="java"></rabbit:binding>
</rabbit:bindings>
</rabbit:direct-exchange>
<bean id="javaListener" class="rabbitmq.spring.listener.JavaListener"></bean>
<bean id="erlandListener" class="rabbitmq.spring.listener.ErlandListener"></bean>
<bean id="javaProducer" class="rabbitmq.spring.producer.JavaProducer"></bean>
<bean id="erlandProducer" class="rabbitmq.spring.producer.ErlandProducer"></bean>
<rabbit:listener-container
connection-factory="connectionFactory"
acknowledge="manual"
concurrency="20"
max-concurrency="50"
requeue-rejected="false">
<rabbit:listener ref="javaListener" queue-names="program.java.queue"/>
<rabbit:listener ref="erlandListener" queue-names="program.erland.queue"/>
</rabbit:listener-container>
</beans>
applicationContext-test.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!--<context:component-scan base-package="rabbitmq.spring"></context:component-scan>-->
<import resource="classpath*:rabbit-mq.xml"/>
</beans>
Producer
Producer
public abstract class Producer {
@Resource(name = "programTemplate")
AmqpTemplate amqpTemplate;
protected abstract String routeKey();
public void produce(Programmer log) {
try {
Message message = MessageBuilder.withBody(JSON.toJSONString(log).getBytes())
.setContentType(MessageProperties.CONTENT_TYPE_JSON)
.setDeliveryMode(MessageDeliveryMode.PERSISTENT)
.setMessageId(UUID.randomUUID().toString())
.build();
amqpTemplate.convertAndSend(routeKey(), message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
JavaProducer
@Component
public class JavaProducer extends Producer {
@Override
protected String routeKey() {
return "java";
}
}
UML graphics
It's not enough to monitor, get it in
one go ProgramListener
public abstract class ProgramListener implements ChannelAwareMessageListener {
final Logger logger = LoggerFactory.getLogger(this.getClass());
public void onMessage(Message message, Channel channel) throws Exception {
try {
logger.info("Receive message, message body -> {}", new String(message.getBody()));
channel.basicAck(message.getMessageProperties().getDeliveryTag(), true);
} catch (Exception e) {
logger.error("exception", e);
channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
}
}
}
JavaListener
public class JavaListener extends ProgramListener {
}
At this point, the configuration and monitoring of rabbitmq has been completed. The configuration adopts the direct mode in rabbitmq.
Write a unit test to verify
RabbitMqMain
package com;
import org.junit.Test;
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;
import rabbitmq.spring.entity.Programmer;
import rabbitmq.spring.producer.JavaProducer;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/applicationContext-test.xml")
//@TestExecutionListeners({/*ServletTestExecutionListener.class, */DependencyInjectionTestExecutionListener.class/*,
// DirtiesContextTestExecutionListener.class*/})
public class RabbitMqMain {
@Autowired
JavaProducer javaProducer;
@Test
public void testSend() {
Programmer programmer = new Programmer();
programmer.setMessage("i am java, do u know me?");
javaProducer.produce(programmer);
}
}
Can run normally.
Attach the rabbitmq console information: