从ActiveMQConnectionFactory创建经过身份验证的XA资源

时间:2016-08-31 11:56:19

标签: spring-transactions spring-jms xa atomikos activemq-artemis

我有一个Apache ActiveMQ Artemis(1.3)实例,我正试图从我的团队目前正在处理的独立Spring(4.3.2)应用程序进行连接。它使用Atomikos(4.0.4) UserTransactionManager 作为提供程序使用Spring JTATransactionManager ,在这些事务中,我需要连接到多个资源,包括前面提到的MQ。在Artemis和Atomikos手册之后,我们设置了 ActiveMQConnectionFactory ,然后将其传递给 AtomikosConnectionFactoryBean 。这一切都发生在Spring容器中,但这似乎与我们的问题无关。

在我尝试向MQ连接添加身份验证之前,这一切都运行良好。可以在 ActiveMQConnectionFactory 的实例上设置用户密码属性,但是,它们似乎仅在创建普通连接时才考虑:

@Override
public Connection createConnection() throws JMSException {
  return createConnection(user, password);
}

@Override
public Connection createConnection(final String username, final String password) throws JMSException {
  return createConnectionInternal(username, password, false, ActiveMQConnection.TYPE_GENERIC_CONNECTION);
}

Atomikos正在调用 createXAConnection ()方法(来自 XAConnectionFactory 接口),正如我在其实现中看到的那样,除非明确传递,否则忽略凭证:

@Override
public XAConnection createXAConnection() throws JMSException {
  return createXAConnection(null, null);
}

@Override
public XAConnection createXAConnection(final String username, final String password) throws JMSException {
  return (XAConnection) createConnectionInternal(username, password, true, ActiveMQConnection.TYPE_GENERIC_CONNECTION);
}

这是这个类中其他一些方法的工作方式,因此我认为它不是一个bug。如果是这样,我应该如何获得经过身份验证的 XAConnection ?我没有看到Atomikos调用重载版本的可能性,看看它的代码。

此致 的Jakub

1 个答案:

答案 0 :(得分:0)

作为一种解决方法,我们决定将 ActiveMQConnectionFactory 包装在实现必要接口的类中:

public class ActiveMQConnectionFactoryWrapper implements XAConnectionFactory {

  private final ActiveMQConnectionFactory factory;

  public ActiveMQConnectionFactoryWrapper(ActiveMQConnectionFactory factory) {
    this.factory = factory;
  }

  @Override
  public XAConnection createXAConnection() throws JMSException {
    return factory.createXAConnection(factory.getUser(), factory.getPassword());
  }

  @Override
  public XAConnection createXAConnection(String userName, String password) throws JMSException {
    return factory.createXAConnection(userName, password);
  }

  @Override
  public XAJMSContext createXAContext() {
    return factory.createXAContext(factory.getUser(), factory.getPassword());
  }

  @Override
  public XAJMSContext createXAContext(String userName, String password) {
    return factory.createXAContext(userName, password);
  }
}

如果需要,也可以实现其他接口。