如何在spring boot中实现jms队列

     2023-02-16     29

关键词:

【中文标题】如何在spring boot中实现jms队列【英文标题】:How to implement jms queue in spring boot 【发布时间】:2017-04-17 08:58:00 【问题描述】:

我已经使用初始化程序创建了一个 Spring Boot 项目,我正在尝试创建我的第一条消息,但我不知道从哪里开始。我熟悉使用 JEE 的相同过程,所以我想我需要创建一个工厂、一个发送者和一个消费者。

谁能帮帮我?

【问题讨论】:

【参考方案1】:

最好的起点是projects getting started guide

你的方法在一般意义上是正确的,但他就是骨架的样子。

第一个 spring-boot 为您提供了一个完美的配置文件结构,如果您使用像 Netbeans 这样的智能 ide,那么通过添加 spring-boot 插件也会在属性文件中为您提供自动完成功能。由于 Spring 对每个代理的行为略有不同,因此在我的示例中,我将使用 ActiveMQ

通过在我们的构建路径上添加 ActiveMQ,Spring Boot 将自动设置一个 ActiveMQ 代理。我们需要设置几个属性以使其成为内存代理,而无需连接池。我们可以通过为 Spring Boot 设置两个属性来做到这一点。

spring.activemq.in-memory=true
spring.activemq.pooled=false
jms.bookmgrqueue.name=book-mgr-queue #queue name

其他代理也可以进行类似的配置。

首先,您开始设置 Spring 应用程序。您应该放置 @EnableJms 注释以启用 Jms 支持,然后设置一个新队列。

例子

@EnableJms
@Configuration
public class JmsConfiguration 

    @Autowired
    private BeanFactory springContextBeanFactory;

    @Bean
    public DefaultJmsListenerContainerFactory containerFactory(ConnectionFactory connectionFactory) 
        DefaultJmsListenerContainerFactory factory =
                new DefaultJmsListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setDestinationResolver(new BeanFactoryDestinationResolver(springContextBeanFactory));
        factory.setConcurrency("3-10");
        return factory;
    

    @Bean
    public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) throws JMSException 
        return new JmsTemplate(connectionFactory);
    


收听队列消息

侦听器组件 (BookMgrQueueListener.java) 使用 Spring 的 @JmsListener 注释和选择器来读取具有给定 Operation 标头的消息。

@Component
public class BookMgrQueueListener implements Loggable

    private final BookService bookService;

    @Autowired
    public BookMgrQueueListener(BookService bookService) 
        this.bookService = bookService;
    

    @JmsListener(containerFactory = "containerFactory",
                 destination = "bookMgrQueueDestination",
                 selector = "Operation = 'Create'")
    public void processCreateBookMessage(BookDTO book) throws JMSException
        bookService.createNew(book);
    

    @JmsListener(containerFactory = "containerFactory",
                 destination = "bookMgrQueueDestination",
                 selector = "Operation = 'Update'")
    public void processUpdateBookMessage(BookDTO book) throws JMSException
        bookService.update(book.getIsbn(), book);
    

    @JmsListener(containerFactory = "containerFactory",
                 destination = "bookMgrQueueDestination",
                 selector = "Operation = 'Delete'")
    public void processDeleteBookMessage(BookDTO book) throws JMSException
        bookService.delete(book.getIsbn());
    


用于测试的活动 MQ

为了测试配置,我们在一个新的配置文件 ActiveMqConfiguration.java 中设置了 activeMq 代理。

@Configuration
public class ActiveMqConfiguration 

    public static final String ADDRESS = "vm://localhost";

    private BrokerService broker;

    @Bean(name="bookMgrQueueDestination")
    public Destination bookMgrQueueDestination(@Value("$jms.bookmgrqueue.name") String bookMgrQueueName)
            throws JMSException 
        return new ActiveMQQueue(bookMgrQueueName);
    

    @PostConstruct
    public void startActiveMQ() throws Exception 
        broker = new BrokerService();
        // configure the broker
        broker.setBrokerName("activemq-broker");
        broker.setDataDirectory("target");
        broker.addConnector(ADDRESS);
        broker.setUseJmx(false);
        broker.setUseShutdownHook(false);
        broker.start();
    

    @PreDestroy
    public void stopActiveMQ() throws Exception 
        broker.stop();
    

    @Bean
    public ConnectionFactory connectionFactory() 
        return new ActiveMQConnectionFactory(ADDRESS + "?broker.persistent=false");
    

我们正在测试用例中设置完整的应用程序上下文,但我们正在将侦听器中的 BookService 引用替换为 MockedBookService,我们将使用它来验证是否执行了正确的调用。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Application.class, loader = SpringApplicationContextLoader.class)
@WebAppConfiguration
public class BookMgrQueueListenerIntegrationTest 

    @Autowired(required = false)
    private JmsTemplate jmsTemplate;

    @Autowired
    private BookMgrQueueListener bookMgrQueueListener;


    @Autowired(required = false)
    @Qualifier("bookMgrQueueDestination")
    private Destination bookMgrQueueDestination;

    @Mock
    private BookService mockBookService;

    @Captor
    private ArgumentCaptor<BookDTO> bookArgumentCaptor;

    @Before
    public void setUp()
        MockitoAnnotations.initMocks(this);
        ReflectionTestUtils.setField(bookMgrQueueListener, "bookService", mockBookService);
    

    /* ... tests */

最后,我们为所有操作添加测试,并验证是否使用正确的操作和参数调用了服务层。

/* ... */
public class BookMgrQueueListenerIntegrationTest 
    /* ... */
    @Test
    public void testSendCreateBookMessage()
        BookDTO book =  new BookDTO("isbn", "title", "author");
        jmsTemplate.convertAndSend(bookMgrQueueDestination, book, Message -> 
            return OperationHeader.CREATE.applyToMessage(Message);
        );
        // verify
        verify(mockBookService).createNew(bookArgumentCaptor.capture());
        assertEquals(book.getIsbn(), bookArgumentCaptor.getValue().getIsbn());
        assertEquals(book.getTitle(), bookArgumentCaptor.getValue().getTitle());
        assertEquals(book.getAuthor(), bookArgumentCaptor.getValue().getAuthor());
    

    @Test
    public void testSendUpdateBookMessage()
        BookDTO book =  new BookDTO("isbn", "title", "author");
        jmsTemplate.convertAndSend(bookMgrQueueDestination, book, Message -> 
            return OperationHeader.UPDATE.applyToMessage(Message);
        );
        // verify
        verify(mockBookService).update(eq(book.getIsbn()), bookArgumentCaptor.capture());
        assertEquals(book.getIsbn(), bookArgumentCaptor.getValue().getIsbn());
        assertEquals(book.getTitle(),bookArgumentCaptor.getValue().getTitle());
        assertEquals(book.getAuthor(),bookArgumentCaptor.getValue().getAuthor());
    

    @Test
    public void testSendDeleteBookMessage()
        BookDTO book =  new BookDTO("isbn", "title", "author");
        jmsTemplate.convertAndSend(bookMgrQueueDestination, book, Message -> 
            return OperationHeader.DELETE.applyToMessage(Message);
        );
        // verify
        verify(mockBookService).delete(book.getIsbn());
    

我们很高兴!

参考Integrate JMS queue into a Spring Application

【讨论】:

非常感谢!这很有帮助! 很好的答案和参考资料。对那些想用 jmslistener 注释方法在 bean 上 Mockito.spy() 的人来说只是一个警告:间谍阻止它实际监听队列。

如何在 Spring Boot 中实现 Camunda SendTask

】如何在SpringBoot中实现CamundaSendTask【英文标题】:HowtoimplementCamundaSendTaskinSpringBoot【发布时间】:2020-10-0914:06:21【问题描述】:我是Camunda的新手,正在使用以下任务:业务规则任务-->(网关)-->发送任务-->用户任务在使... 查看详情

如何在 Spring Boot 中实现基于角色权限的系统

】如何在SpringBoot中实现基于角色权限的系统【英文标题】:HowtoimplementRolePermissionbasedsysteminSpringBoot【发布时间】:2016-11-0919:14:30【问题描述】:我正在尝试使用springboot和springsecurity来实现基于角色权限的系统。为此,我以http://w... 查看详情

如何使用hibernate在spring boot中实现分页

】如何使用hibernate在springboot中实现分页【英文标题】:Howtoimplementpaginationinspringbootwithhibernate【发布时间】:2015-12-0217:41:44【问题描述】:我正在使用带有休眠功能的SpringBoot,并且我想在我的项目中使用分页。我在谷歌上搜索并... 查看详情

如何在 Spring Boot 中实现部分 GET 请求?

】如何在SpringBoot中实现部分GET请求?【英文标题】:HowtoimplementpartialGETrequestsinSpringBoot?【发布时间】:2021-09-1918:47:58【问题描述】:我正在尝试实现一个控制器,该控制器将接受请求标头中的字节范围,然后将多媒体作为字节... 查看详情

如何使用spring boot jms收听话题

】如何使用springbootjms收听话题【英文标题】:Howtolistentotopicusingspringbootjms【发布时间】:2017-03-0120:54:29【问题描述】:我正在尝试使用以下sn-p收听主题。但是默认情况下它会监听队列。在这种情况下没有xml配置。我完全依赖注... 查看详情

如何在 Spring Boot 应用程序中实现长轮询 REST 端点?

】如何在SpringBoot应用程序中实现长轮询REST端点?【英文标题】:HowtoimplementLongPollingRESTendpointinSpringBootapp?【发布时间】:2019-05-1021:18:31【问题描述】:您能否分享任何最新的手册或在这里解释如何使用最新的Spring(SpringBoot)实现RE... 查看详情

如何在 Spring Boot 中实现 oAuth2 和 JWT 身份验证? [关闭]

】如何在SpringBoot中实现oAuth2和JWT身份验证?[关闭]【英文标题】:HowtoimplementoAuth2alongwithJWTauthenticationinspringboot?[closed]【发布时间】:2015-10-3002:31:17【问题描述】:我正在使用jhipster和mongodb作为主数据库创建一个SpringBootWeb应用程... 查看详情

如何在优雅地spring中实现消息的发送和消费

...的开发细节,然后通过一个简单的示例来一步一步的讲解如何使用这个spring-boot-starter工具包来配置,发送和消费RocketMQ消息。作者简介:辽天,阿里巴巴技术专家,ApacheRocketMQ内核控,拥有多年分 查看详情

如何在 Spring Boot 中实现通用 JPA 存储库 - 它可以自动装配到任何实体/类类型的 Spring 服务中

】如何在SpringBoot中实现通用JPA存储库-它可以自动装配到任何实体/类类型的Spring服务中【英文标题】:HowtoimplementGenericJPARepositoryinSpringBoot-Whichcanbeautowiredintospringservicesforanyentity/classtype【发布时间】:2016-02-0408:07:27【问题描述】... 查看详情

在 Spring Boot 中实现“注销”功能

】在SpringBoot中实现“注销”功能【英文标题】:Implement\'logout\'functionalityinSpringBoot【发布时间】:2014-07-0221:53:37【问题描述】:为了让基本的安全功能正常工作,我在我的pom.xml中添加了以下启动包<dependency><groupId>org.spri... 查看详情

带有 tibco jms 监听器的 Spring Boot

...bcoems队列(想要基于注释的配置)。我没有看到任何描述如何从SpringBoot配置和侦听Tibcoems队列的示例。有这方面的线索或例子吗?【问题讨论】:【参考方案1】:在springboot应用类中创建连 查看详情

SCD (slowly changed dimension) Type 4/6 - 如何在spring boot app, hibernate envers中实现

】SCD(slowlychangeddimension)Type4/6-如何在springbootapp,hibernateenvers中实现【英文标题】:SCD(slowlychangingdimension)Type4/6-howtoimplementinspringbootapp,hibernateenvers【发布时间】:2021-03-0715:52:55【问题描述】:我正在尝试解决这个问题,我应该如何... 查看详情

在spring boot中实现自定义错误

】在springboot中实现自定义错误【英文标题】:Implementthecustomerrorinspringboot【发布时间】:2019-04-0702:58:26【问题描述】:我想页面。在应用程序中,id是主键,所以当没有给出id时,它会将请求传输到页面,但我希望应用程序在索... 查看详情

在spring boot中实现自己的内存缓存机制

】在springboot中实现自己的内存缓存机制【英文标题】:Implementowninmemorycachemechanisminspringboot【发布时间】:2021-12-2323:11:19【问题描述】:我被要求在我的SpringBoot应用程序中实现内存缓存机制。我的申请与社交媒体有关。用户可以... 查看详情

无法在 Spring Boot 中实现 Drools KieSession Persistence

】无法在SpringBoot中实现DroolsKieSessionPersistence【英文标题】:CannotimplementDroolsKieSessionPersistenceinSpringBoot【发布时间】:2021-01-2102:17:00【问题描述】:我试图在SpringBootMaven项目中使用KieSession的持久性功能实现Drools。关注thisdocumentatio... 查看详情

尝试使用 Spring Boot 使用 JMS 主题消息时出现异常

】尝试使用SpringBoot使用JMS主题消息时出现异常【英文标题】:ExceptionwhiletryingtoconsumeaJMSTopicmessageusingSpringBoot【发布时间】:2020-07-2019:54:42【问题描述】:我正在尝试使用来自ActiveMQ主题的消息。下面是代码:@Configuration@EnableJmspub... 查看详情

Spring Boot:加载所有在测试中实现接口的bean?

】SpringBoot:加载所有在测试中实现接口的bean?【英文标题】:SpringBoot:loadallbeansimplementinganinterfaceintest?【发布时间】:2020-12-1920:22:51【问题描述】:我有一些接口Filter和这个接口的一些实现。在@Test中,我想加载所有实现Filter的... 查看详情

我已经在 Spring Boot 代码中实现了 JWT 令牌安全性。如何在我的代码中的任何地方获取 jwt 令牌?需要保存审核

】我已经在SpringBoot代码中实现了JWT令牌安全性。如何在我的代码中的任何地方获取jwt令牌?需要保存审核【英文标题】:IhaveimplementedJWTtokensecurityinspringbootcode.howwillIgetjwttokenanywhereinmycode?needtosaveaudit【发布时间】:2021-04-0401:22:57... 查看详情