У меня есть исходящий шлюз для мыльных вызовов (MarshallingWebServiceOutboundGateway) со сложной настройкой.Мне нужно использовать это определение шлюза из нескольких потоков.Вопрос пружинная интеграция: на MessageProducer можно ссылаться только после того, как чем-то похож, но этот вопрос касается правильного использования прототипа области действия bean-компонента Spring для соавторов интеграции.
У меня естьотдельный файл конфигурации, который устанавливает шлюз и его зависимости:
@Bean
public MarshallingWebServiceOutboundGateway myServiceGateway() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("blah.*");
MarshallingWebServiceOutboundGateway gateway = new MarshallingWebServiceOutboundGateway(
serviceEndpoint, marshaller, messageFactory);
gateway.setMessageSender(messageSender);
gateway.setRequestCallback(messageCallback);
return gateway;
}
Вот как я изначально пытался подключить исходящий шлюз из двух разных потоков в двух разных файлах конфигурации.
Водин файл конфигурации:
@Bean
public IntegrationFlow flow1() {
MarshallingWebServiceOutboundGateway myServiceGateway = context.getBean("myServiceGateway", MarshallingWebServiceOutboundGateway.class);
return IntegrationFlows
.from(Http.inboundGateway("/res1")
.requestMapping(r -> r.methods(HttpMethod.GET))
.transform(soapRequestTransformer)
.handle(myServiceGateway) // wrong: cannot be same bean
.transform(widgetTransformer)
.get();
}
В отдельном файле конфигурации:
@Bean
public IntegrationFlow flow2() {
MarshallingWebServiceOutboundGateway myServiceGateway = context.getBean("myServiceGateway", MarshallingWebServiceOutboundGateway.class);
return IntegrationFlows
.from(Http.inboundGateway("/res2")
.requestMapping(r -> r.methods(HttpMethod.GET))
.transform(soapRequestTransformer)
.handle(myServiceGateway) // wrong: cannot be same bean
.transform(widgetTransformer)
.handle(servicePojo)
.get();
}
Это проблема, потому что - насколько я понимаю - myServiceGateway
не может быть одним и тем же экземпляром, посколькуЭкземпляр имеет только один исходящий канал и не может принадлежать двум разным потокам.
В связанном вопросе весенняя интеграция: на MessageProducer можно ссылаться только один раз , @ artem-bilan рекомендуется не создаватьисходящий шлюз в методе @Bean
, а не простой метод, который создает новые экземпляры для каждого вызова.
Это работает, но это неудобно в моем случае.Мне нужно повторно использовать исходящий шлюз из нескольких потоков в разных файлах конфигурации, и мне нужно было бы скопировать код для создания шлюза в каждом файле конфигурации.Кроме того, зависимости шлюза раздувают мои конструкторы конфигурационного файла, заставляя сонар под залог.
Поскольку сообщение об ошибке, выходящее из IntegrationFlowDefinition.checkReuse()
, говорит A reply MessageProducer may only be referenced once (myServiceGateway) - use @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) on @Bean definition.
, я хотел еще раз попробовать прототип области видимости.
Итак, я пытаюсь заставить Spring интеграции искать прототип шлюза из контекста по имени, надеясь получить другой экземпляр шлюза в flow1 и flow2:
.handle(context.getBean("myServiceGateway",
MarshallingWebServiceOutboundGateway.class))
И я аннотировал исходящийшлюз @ Определение бина с
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
Но я вижу, что метод myServiceGateway()
вызывается только один раз, несмотря на область действия прототипа, и при запуске приложения все еще происходит сбой с сообщением об ошибке, в котором рекомендуется использовать область действия прототипа- довольно запутанно, на самом деле; -)
Основано на Тайна вокруг Spring Integration и прототип * Я также попробовал:
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)
Приложение запускается, но ответы никогда недоберитесь до шага после ворот, widgetTransformer
.(Еще более странно, что именно widgetTransformer
пропускается: в flow1
результатом является нетрансформированный ответ шлюза, а в flow2
нетрансформированные сообщения попадают на шаг после элемента widgetTransformer, то есть servicePojo
).Создание прокси-сервера из производителя сообщений, похоже, не очень хорошая идея.
Я действительно хочу докопаться до сути.Неправильное сообщение об исключении, которое просит использовать область прототипа, или я просто получаю это неправильно?Как можно избежать повторения определения bean-компонента для производителей сообщений, если мне нужно несколько таких производителей, которые настроены одинаково?
Использование Spring-интеграции 5.0.9.