当前位置: 代码迷 >> java >> Spring Boot:使用 Java Bean 类从 application.properties 文件中读取 spring.jms.jndi-name 属性
  详细解决方案

Spring Boot:使用 Java Bean 类从 application.properties 文件中读取 spring.jms.jndi-name 属性

热度:63   发布时间:2023-08-02 10:25:59.0

我正在使用JNDI 查找在 tomcat 服务器上获取Websphere MQ Broker 的连接对象。 我正在使用JmsTemplate将消息发送到 WMQ Broker 上的队列并试图避免基于 Spring Xml 的配置,因此我配置了 Spring boot 的 application.properties 文件以指定JNDI 查找名称。下面是来自application.properties 文件。

spring.jms.jndi-name= java:comp/env/XXXX

我正在使用 Spring bean 来定义 JmsTemplate,下面是它的代码。

@Configuration
public class JmsMessageTemplateBean {

    //@Value("${spring.jms.jndi-name}")
    //private ConnectionFactory connectionFactory;

    @Bean
    public JmsTemplate jmsTemplate() throws Exception{
        JmsTemplate jmsMessagingTemplate = new JmsTemplate();
        jmsMessagingTemplate.setDefaultDestinationName("Some Queue");
        jmsMessagingTemplate.setConnectionFactory(connectionFactory);
        return jmsMessagingTemplate;
    }
}

我有一些问题:

1.如何从application.properties文件中读取JNDI属性并将Connection对象设置为上述bean中的Jms Template。

2.我观察到来自JNDI 查找的连接对象是MQQueueConnectionFactory并且从我研究的JmsTemplate支持javax.jms.ConnectionFactory对象。 有没有办法将MQQueueConnectionfactory对象转换为javax.jms.Connectionfactory

感谢您的回答。

我也很难弄清楚如何实现 Spring Boot JMS 侦听器,侦听 JBoss 应用程序服务器中的 ActiveMQ 队列。

Spring Boot 自动配置支持 ActiveMQ,但由于它在 JBoss 服务器内部,Spring Boot 无法连接 ActiveMQ。 实际上,您需要通过对 JNDI 提供程序进行查找来自己定义connectionFactoryjmsListenerContainerFactory bean。

@Configuration
@EnableJms
public class ActiveMqConnectionFactoryConfig {

  @Value("${broker.url}")
  String brokerUrl;

  @Value("${borker.username}")
  String userName;

  @Value("${borker.password}")
  String password;

  @Value("${queue}")
  String queueName;

  private static final String INITIAL_CONTEXT_FACTORY = "org.jboss.naming.remote.client.InitialContextFactory";
  private static final String CONNECTION_FACTORY = "jms/RemoteConnectionFactory";


  @Bean
  public ConnectionFactory connectionFactory() {
    try {
      System.out.println("Retrieving JMS queue with JNDI name: " + CONNECTION_FACTORY);
      JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
      jndiObjectFactoryBean.setJndiName(CONNECTION_FACTORY);

      jndiObjectFactoryBean.setJndiEnvironment(getEnvProperties());
      jndiObjectFactoryBean.afterPropertiesSet();

      return (QueueConnectionFactory) jndiObjectFactoryBean.getObject();

    } catch (NamingException e) {
      System.out.println("Error while retrieving JMS queue with JNDI name: [" + CONNECTION_FACTORY + "]");
    } catch (Exception ex) {
      System.out.println("Error");
    }
    return null;
  }

  Properties getEnvProperties() {
    Properties env = new Properties();
    env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
    env.put(Context.PROVIDER_URL, brokerUrl);
    env.put(Context.SECURITY_PRINCIPAL, userName);
    env.put(Context.SECURITY_CREDENTIALS, password);
    return env;
  }

  @Bean
  public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(ConnectionFactory connectionFactory) {

    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    JndiDestinationResolver jndiDestinationResolver = new JndiDestinationResolver();

    jndiDestinationResolver.setJndiEnvironment(getEnvProperties());
    factory.setDestinationResolver(jndiDestinationResolver);
    return factory;
  }

然后,如果您想使用队列,您只需使用@JmsListener(destination = "${queue}")注释的方法定义 JMS 使用者类

 @JmsListener(destination = "${queue}")
  public void receive(Message message) {
    System.out.println("Received Message: " + message);
  }

希望这有助于节省几个小时的研究;) 干杯

  相关解决方案