Spring Boot 多个@Configuration 和 SOAP 客户端
SpringBoot multiple @Configuration and SOAP clients
我尝试按照这个简单的教程进行操作 https://spring.io/guides/gs/consuming-web-service/,并且有效。
然后我尝试连接到另一个 SOAP 服务,附加 @Configuration
和客户端-class 扩展 WebServiceGatewaySupport
。似乎两个 client-classes 然后使用相同的 @Configuration
-class,使我添加的第一个失败(未知的 jaxb-context 等)。如何确保客户端-classes 使用正确的@Configuration
-class?
我最终在 returns 和 WebServiceTemplate
的 @Configuration-class 中创建了 @Bean。也就是说,我不使用 Spring 的自动配置机制。我删除了 extend WebserviceGatewaySupport
,并使用 @Autowired
自动装配在 @Configuration
class 中创建的 WebserviceTemplateBean
bean。
TL;DR: 您必须将 "marshaller()" 方法的名称与客户端配置中的参数变量名称相匹配。
覆盖 bean 定义
发生的事情是你的两个@Configuration 类都为 Jaxb2Marshaller 使用相同的 bean 名称,即(使用 spring 示例):
@Bean
public Jaxb2Marshaller marshaller() { //<-- that name
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("hello.wsdl");
return marshaller;
}
"marshaller()" 方法名称是将在您的客户端下面注入的 bean 名称:
@Bean
public QuoteClient quoteClient(Jaxb2Marshaller marshaller) { //<-- used here
QuoteClient client = new QuoteClient();
client.setDefaultUri("http://www.webservicex.com/stockquote.asmx");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
return client;
}
如果您对第二个客户端使用 "marshaller()",则 Spring 会覆盖该 bean 定义。您可以在日志文件中发现这一点,查找类似这样的内容:
INFO 7 --- [main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'marshaller'
解决方案
因此,要创建更多拥有自己的编组器而不会发生冲突的客户端,您需要像这样的 @Configuration:
@Configuration
public class ClientBConfiguration {
@Bean
public Jaxb2Marshaller marshallerClientB() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("hello.wsdl");
return marshaller;
}
@Bean
public ClientB clientB(Jaxb2Marshaller marshallerClientB) {
ClientB client = new ClientB();
client.setDefaultUri("http://www.webservicex.com/stockquote.asmx");
client.setMarshaller(marshallerClientB);
client.setUnmarshaller(marshallerClientB);
return client;
}
}
- 关于 bean 覆盖的更多信息:https://blog.tratif.com/2018/03/08/when-two-beans-collide/
- 关于 spring 启动 @Configuration 类 的回答:
我尝试按照这个简单的教程进行操作 https://spring.io/guides/gs/consuming-web-service/,并且有效。
然后我尝试连接到另一个 SOAP 服务,附加 @Configuration
和客户端-class 扩展 WebServiceGatewaySupport
。似乎两个 client-classes 然后使用相同的 @Configuration
-class,使我添加的第一个失败(未知的 jaxb-context 等)。如何确保客户端-classes 使用正确的@Configuration
-class?
我最终在 returns 和 WebServiceTemplate
的 @Configuration-class 中创建了 @Bean。也就是说,我不使用 Spring 的自动配置机制。我删除了 extend WebserviceGatewaySupport
,并使用 @Autowired
自动装配在 @Configuration
class 中创建的 WebserviceTemplateBean
bean。
TL;DR: 您必须将 "marshaller()" 方法的名称与客户端配置中的参数变量名称相匹配。
覆盖 bean 定义
发生的事情是你的两个@Configuration 类都为 Jaxb2Marshaller 使用相同的 bean 名称,即(使用 spring 示例):
@Bean
public Jaxb2Marshaller marshaller() { //<-- that name
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("hello.wsdl");
return marshaller;
}
"marshaller()" 方法名称是将在您的客户端下面注入的 bean 名称:
@Bean
public QuoteClient quoteClient(Jaxb2Marshaller marshaller) { //<-- used here
QuoteClient client = new QuoteClient();
client.setDefaultUri("http://www.webservicex.com/stockquote.asmx");
client.setMarshaller(marshaller);
client.setUnmarshaller(marshaller);
return client;
}
如果您对第二个客户端使用 "marshaller()",则 Spring 会覆盖该 bean 定义。您可以在日志文件中发现这一点,查找类似这样的内容:
INFO 7 --- [main] o.s.b.f.s.DefaultListableBeanFactory : Overriding bean definition for bean 'marshaller'
解决方案
因此,要创建更多拥有自己的编组器而不会发生冲突的客户端,您需要像这样的 @Configuration:
@Configuration
public class ClientBConfiguration {
@Bean
public Jaxb2Marshaller marshallerClientB() {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("hello.wsdl");
return marshaller;
}
@Bean
public ClientB clientB(Jaxb2Marshaller marshallerClientB) {
ClientB client = new ClientB();
client.setDefaultUri("http://www.webservicex.com/stockquote.asmx");
client.setMarshaller(marshallerClientB);
client.setUnmarshaller(marshallerClientB);
return client;
}
}
- 关于 bean 覆盖的更多信息:https://blog.tratif.com/2018/03/08/when-two-beans-collide/
- 关于 spring 启动 @Configuration 类 的回答: