我确实有一个Spring Boot 5应用程序,并且我还可以在一台IBM MQ服务器上运行它。
现在,我们希望它连接到三个或更多MQ服务器。现在,我的意图是将XY连接信息添加到环境中,然后获得XY MQConnectionFactory bean和其他处理所需的bean。
目前,这是我所拥有的:
@Bean
@Qualifier(value="MQConnection")
public MQConnectionFactory getIbmConnectionFactory() throws JMSException {
MQConnectionFactory factory = new MQConnectionFactory();
// seeting all the parameters here
return factory;
}
但这是静态的。是否有一种优雅的方法?
我偶然发现了IntegrationFlow。这可能是可行的解决方案吗?
感谢您的小费!
韩国
根据Artem Bilan的回应,我建立了这个课程。
@Configuration
public class ConnectionWithIntegrationFlowMulti {
protected static final Logger LOG = Logger.create();
@Value("${mq.queue.jms.sources.queue.queue-manager}")
private String queueManager;
@Autowired
private ConnectionConfig connectionConfig;
@Autowired
private SSLSocketFactory sslSocketFactory;
@Bean
public MessageChannel queureader() {
return new DirectChannel();
}
@Autowired
private IntegrationFlowContext flowContext;
@PostConstruct
public void processBeanDefinitionRegistry() throws BeansException {
Assert.notEmpty(connectionConfig.getTab().getLocations(), "At least one CCDT file locations must be provided.");
for (String tabLocation : connectionConfig.getTab().getLocations()) {
try {
IntegrationFlowRegistration theFlow = this.flowContext.registration(createFlow(tabLocation)).register();
LOG.info("Registered bean flow for %s with id = %s", queueManager, theFlow.getId());
} catch (JMSException e) {
LOG.error(e);
}
}
}
public IntegrationFlow createFlow(String tabLocation) throws JMSException {
LOG.info("creating ibmInbound");
return IntegrationFlows.from(Jms.messageDrivenChannelAdapter(getConnection(tabLocation)).destination(createDestinationBean()))
.handle(m -> LOG.info("received payload: " + m.getPayload().toString()))
.get();
}
public MQConnectionFactory getConnection(String tabLocation) throws JMSException {
MQConnectionFactory factory = new MQConnectionFactory();
// doing stuff
return factory;
}
@Bean
public MQQueue createDestinationBean() {
LOG.info("creating destination bean");
MQQueue queue = new MQQueue();
try {
queue.setBaseQueueManagerName(queueManager);
queue.setBaseQueueName(queueName);
} catch (Exception e) {
LOG.error(e, "destination bean: Error for integration flow");
}
return queue;
}
}
使用Spring Integration,您可以IntegrationFlow
在运行时动态创建实例。为此,IntegrationFlowContext
它带有一个registration()
API。返回IntegrationFlowRegistrationBuilder
作为回调,如:
/**
* Add an object which will be registered as an {@link IntegrationFlow} dependant bean in the
* application context. Usually it is some support component, which needs an application context.
* For example dynamically created connection factories or header mappers for AMQP, JMS, TCP etc.
* @param bean an additional arbitrary bean to register into the application context.
* @return the current builder instance
*/
IntegrationFlowRegistrationBuilder addBean(Object bean);
因此,您的MQConnectionFactory
实例可以与其他流一起填充,用作特定JMS组件中的引用,也可以注册为bean。
在文档中查看更多信息:https : //docs.spring.io/spring-integration/docs/5.2.3.RELEASE/reference/html/dsl.html#java-dsl-runtime-flows
谢谢。我正在研究它,并尝试实现它。但是,以编程方式注册这些bean的正确位置在哪里?我考虑过,
implements BeanDefinitionRegistryPostProcessor
但那里没有用于连接的环境变量。@PostConstruct
在某些情况下@Configuration
,注入的对象IntegrationFlowContext
应该足以迭代环境并向可能的支持bean注册动态流。