SpringAMQP的简要实现

1.Basic Queue 简单队列模型

1.1导入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

1.2 yaml

spring:
  rabbitmq:
    host: 192.168.150.101 # 主机名
    port: 5672 # 端口
    virtual-host: / # 虚拟主机
    username: itcast # 用户名
    password: 123321 # 密码

1.3 消息发送

package cn.itcast.mq.spring;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringAmqpTest {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void testSimpleQueue() {
        // 队列名称
        String queueName = "simple.queue";
        // 消息
        String message = "hello, spring amqp!";
        // 发送消息
        rabbitTemplate.convertAndSend(queueName, message);
    }
}

 1.4消息接收

package cn.itcast.mq.listener;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class SpringRabbitListener {

    @RabbitListener(queues = "simple.queue")
    public void listenSimpleQueueMessage(String msg) throws InterruptedException {
        System.out.println("spring 消费者接收到消息:【" + msg + "】");
    }
}

2.WorkQueue

2.1消息发送

/**
     * workQueue
     * 向队列中不停发送消息,模拟消息堆积。
     */
@Test
public void testWorkQueue() throws InterruptedException {
    // 队列名称
    String queueName = "simple.queue";
    // 消息
    String message = "hello, message_";
    for (int i = 0; i < 50; i++) {
        // 发送消息
        rabbitTemplate.convertAndSend(queueName, message + i);
        Thread.sleep(20);
    }
}

2.2消息接收

@RabbitListener(queues = "simple.queue")
public void listenWorkQueue1(String msg) throws InterruptedException {
    System.out.println("消费者1接收到消息:【" + msg + "】" + LocalTime.now());
    Thread.sleep(20);
}

@RabbitListener(queues = "simple.queue")
public void listenWorkQueue2(String msg) throws InterruptedException {
    System.err.println("消费者2........接收到消息:【" + msg + "】" + LocalTime.now());
    Thread.sleep(200);
}

 2.3yaml 添加属性

spring:
  rabbitmq:
    listener:
      simple:
        prefetch: 1 # 每次只能获取一条消息,处理完成才能获取下一个消息

3.发布/订阅

  • Publisher:生产者,也就是要发送消息的程序,但是不再发送到队列中,而是发给X(交换机)
  • Exchange:交换机,图中的X。一方面,接收生产者发送的消息。另一方面,知道如何处理消息,例如递交给某个特别队列、递交给所有队列、或是将消息丢弃。到底如何操作,取决于Exchange的类型。Exchange有以下3种类型:
    • Fanout:广播,将消息交给所有绑定到交换机的队列
    • Direct:定向,把消息交给符合指定routing key 的队列
    • Topic:通配符,把消息交给符合routing pattern(路由模式) 的队列
  • Consumer:消费者,与以前一样,订阅队列,没有变化
  • Queue:消息队列也与以前一样,接收消息、缓存消息。

3.1Fanout 

 3.1.1 声明交换机和队列

package cn.itcast.mq.config;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FanoutConfig {
    /**
     * 声明交换机
     * @return Fanout类型交换机
     */
    @Bean
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange("itcast.fanout");
    }

    /**
     * 第1个队列
     */
    @Bean
    public Queue fanoutQueue1(){
        return new Queue("fanout.queue1");
    }

    /**
     * 绑定队列和交换机
     */
    @Bean
    public Binding bindingQueue1(Queue fanoutQueue1, FanoutExchange fanoutExchange){
        return BindingBuilder.bind(fanoutQueue1).to(fanoutExchange);
    }

    /**
     * 第2个队列
     */
    @Bean
    public Queue fanoutQueue2(){
        return new Queue("fanout.queue2");
    }

    /**
     * 绑定队列和交换机
     */
    @Bean
    public Binding bindingQueue2(Queue fanoutQueue2, FanoutExchange fanoutExchange){
        return BindingBuilder.bind(fanoutQueue2).to(fanoutExchange);
    }
}

3.1.2消息发送

@Test
public void testFanoutExchange() {
    // 队列名称
    String exchangeName = "itcast.fanout";
    // 消息
    String message = "hello, everyone!";
    rabbitTemplate.convertAndSend(exchangeName, "", message);
}

3.1.3消息接收

@RabbitListener(queues = "fanout.queue1")
public void listenFanoutQueue1(String msg) {
    System.out.println("消费者1接收到Fanout消息:【" + msg + "】");
}

@RabbitListener(queues = "fanout.queue2")
public void listenFanoutQueue2(String msg) {
    System.out.println("消费者2接收到Fanout消息:【" + msg + "】");
}

 3.2Direct

3.2.1基于注解声明队列和交换机,消息接收

@RabbitListener(bindings = @QueueBinding(
    value = @Queue(name = "direct.queue1"),
    exchange = @Exchange(name = "itcast.direct", type = ExchangeTypes.DIRECT),
    key = {"red", "blue"}
))
public void listenDirectQueue1(String msg){
    System.out.println("消费者接收到direct.queue1的消息:【" + msg + "】");
}

@RabbitListener(bindings = @QueueBinding(
    value = @Queue(name = "direct.queue2"),
    exchange = @Exchange(name = "itcast.direct", type = ExchangeTypes.DIRECT),
    key = {"red", "yellow"}
))
public void listenDirectQueue2(String msg){
    System.out.println("消费者接收到direct.queue2的消息:【" + msg + "】");
}

3.2.2消息发送

@Test
public void testSendDirectExchange() {
    // 交换机名称
    String exchangeName = "itcast.direct";
    // 消息
    String message = "红色警报!日本乱排核废水,导致海洋生物变异,惊现哥斯拉!";
    // 发送消息
    rabbitTemplate.convertAndSend(exchangeName, "red", message);
}

3.3Topic

3.3.1 特点

Topic类型的Exchange与Direct相比,都是可以根据RoutingKey把消息路由到不同的队列。

只不过Topic类型Exchange可以让队列在绑定Routing key 的时候使用通配符!  

Routingkey 一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: item.insert  

通配符规则:  #:匹配一个或多个词  *:匹配不多不少恰好1个词  

举例:  item.#:能够匹配item.spu.insert 或者 item.spu  item.*:只能匹配

3.3.2消息发送

/**
     * topicExchange
     */
@Test
public void testSendTopicExchange() {
    // 交换机名称
    String exchangeName = "itcast.topic";
    // 消息
    String message = "喜报!孙悟空大战哥斯拉,胜!";
    // 发送消息
    rabbitTemplate.convertAndSend(exchangeName, "china.news", message);
}

3.3.3消息接收

@RabbitListener(bindings = @QueueBinding(
    value = @Queue(name = "topic.queue1"),
    exchange = @Exchange(name = "itcast.topic", type = ExchangeTypes.TOPIC),
    key = "china.#"
))
public void listenTopicQueue1(String msg){
    System.out.println("消费者接收到topic.queue1的消息:【" + msg + "】");
}

@RabbitListener(bindings = @QueueBinding(
    value = @Queue(name = "topic.queue2"),
    exchange = @Exchange(name = "itcast.topic", type = ExchangeTypes.TOPIC),
    key = "#.news"
))
public void listenTopicQueue2(String msg){
    System.out.println("消费者接收到topic.queue2的消息:【" + msg + "】");
}

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 基于Spring的登录实现代码逻辑如下: 1. 创建一个用户实体类,包含用户名和密码字段。 ```java public class User { private String username; private String password; // 省略getters和setters方法 } ``` 2. 创建一个持久层接口,用于查询用户信息。 ```java public interface UserRepository { User findByUsername(String username); } ``` 3. 创建一个业务层接口,用于处理用户登录逻辑。 ```java public interface UserService { boolean login(String username, String password); } ``` 4. 实现持久层接口,使用数据库查询用户信息。 ```java @Repository public class UserRepositoryImpl implements UserRepository { // 此处省略数据源配置和注入 @Override public User findByUsername(String username) { // 执行数据库查询操作,根据用户名查找用户信息 // 返回查询到的用户对象或null } } ``` 5. 实现业务层接口,处理用户登录逻辑。 ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserRepository userRepository; @Override public boolean login(String username, String password) { User user = userRepository.findByUsername(username); if (user != null && user.getPassword().equals(password)) { // 登录成功 return true; } // 登录失败 return false; } } ``` 6. 创建一个控制器,处理用户登录请求。 ```java @Controller public class LoginController { @Autowired private UserService userService; @RequestMapping("/login") public String login(String username, String password) { boolean result = userService.login(username, password); if (result) { // 登录成功,跳转到首页 return "home"; } else { // 登录失败,返回登录页面并显示错误信息 return "login"; } } } ``` 以上是基于Spring的登录实现代码逻辑的简要说明,其中涉及到了用户实体类、持久层接口和实现、业务层接口和实现、控制器等组件,通过Spring的依赖注入和配置,实现了用户登录的功能。具体的代码实现还需要根据实际需求和技术栈进行进一步的完善和调整。 ### 回答2: 基于Spring的登录实现代码逻辑如下: 首先,需要在Spring的配置文件中配置一个Spring Security的过滤器链。这个过滤器链会拦截所有的URL,检查用户是否已经登录。如果用户未登录,则会跳转到登录页面;如果用户已登录,则可以继续访问其他URL。 接下来,需要创建一个登录页面,包含用户名和密码的输入框,并提交表单到后端。后端会获取到用户输入的用户名和密码。 在后端,可以使用Spring Security提供的认证管理器来进行用户的认证。认证管理器会根据用户输入的用户名和密码,验证用户的身份是否正确。 如果用户身份验证成功,则会生成一个令牌,并将令牌保存在Session中。这样,在后续的请求中,可以通过Session来验证用户的身份。 如果用户身份验证失败,则会返回登录页面,并显示错误的提示信息。 在后端,还可以实现一些权限控制的逻辑。可以使用注解来标记某个URL需要的权限,Spring Security会根据用户的角色或权限来判断用户是否有访问该URL的权限。 如果用户在登录页面选择了“记住我”的选项,则在认证成功后,还可以通过Cookie或Token的方式保存用户的登录状态。这样,在用户关闭浏览器后再次打开时,会自动登录。 以上就是基于Spring的登录实现代码逻辑的简要介绍。具体的实现过程可以参考Spring Security官方文档或相关教程。 ### 回答3: 基于Spring的登录实现代码逻辑通常包括以下几个步骤: 1. 定义用户实体类(User):该类通常包含用户ID、用户名、密码等字段,并通过注解标示为一个实体类。 2. 编写用户服务接口(UserService):该接口定义了用户相关的操作方法,如验证用户名和密码、添加用户信息等。 3. 实现用户服务接口(UserServiceImpl):该类实现了用户服务接口,并通过注解标示为一个Spring的服务组件。在该类中,可以通过依赖注入(Autowired)方式注入数据访问对象(DAO)进行数据库的操作。 4. 定义登录控制器(LoginController):该类负责处理用户登录的请求和响应。在该类中,可以通过依赖注入的方式注入UserService,通过接收请求参数进行逻辑处理,如调用UserService的验证方法判断用户名和密码是否正确,并根据验证结果返回相应的响应。 5. 配置Spring MVC:在Spring的配置文件中配置Spring MVC相关的组件和配置,如控制器、视图解析器等。 6. 编写登录页面(login.jsp):该页面包含用户输入用户名和密码的表单,并通过POST方式提交表单到登录控制器。 以上是基于Spring的登录实现代码逻辑的基本步骤,具体实现还需要根据具体需求进行适当的调整和扩展。例如,可以通过增加验证码等功能提高登录的安全性,通过使用拦截器实现登录状态的验证等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值