Spring Integration: подключение к нескольким серверам MQ по конфигурации - PullRequest
0 голосов
/ 04 февраля 2020

У меня есть приложение Spring Boot 5, и оно также работает на одном сервере IBM MQ.

Теперь мы хотим, чтобы он подключался к трем или более серверам MQ. Теперь я собираюсь добавить информацию о подключении XY в среду, а затем я получу бины XY MQConnectionFactory и все остальные бины, необходимые для обработки.

На данный момент у меня есть следующее:

    @Bean
    @Qualifier(value="MQConnection")
    public MQConnectionFactory getIbmConnectionFactory() throws JMSException {
        MQConnectionFactory factory = new MQConnectionFactory();
// seeting all the parameters here

        return factory;
    }

Но это довольно устоявшееся c. Есть ли элегантный способ сделать это?

Я наткнулся на IntegrationFlow. Это возможно рабочее решение?

Спасибо за все ваши советы!

KR

Решение

Основано на ответе Артема Билана Я построил этот класс.

@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;
    }


}

Ответы [ 2 ]

0 голосов
/ 04 февраля 2020

С помощью 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-потоки

0 голосов
/ 04 февраля 2020

Если у вас все в порядке с их статическим созданием, вы можете создавать бины такими, какие вы есть сейчас (у каждого свой уникальный спецификатор), но вы можете получить динамический доступ ко всем им в ваших сервисах / компонентах, имея поле @Autowired List<MQConnectionFactory> или @Autowired Map<String, MQConnectionFactory> поле. Spring автоматически заполнит поля всеми компонентами типа MQConnectionFactory

. В реализации Map значение квалификатора будет String.

Если вы также хотите создать бины динамически основаны на некоторых свойствах, например c, становится немного сложнее. Вам нужно будет рассмотреть что-то вроде создания экземпляров bean-компонентов во время выполнения

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...