我有一个项目需要使用REST / JSON服务公开我的服务。我使用Spring Boot来开发控制器,然后我通过HTTP Invoker代理注入服务。这个想法起作用,因为我使用XML配置使用基本的Spring 3.2应用程序。但是,我在将HTTP Invoker代理导入Spring Boot应用程序时遇到问题。将它们注入控制器时,它无法找到相关的bean。
错误(使用Gradle构建时的基本单元测试):
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.flashmobilecash.services.PrePaidAirtimeService za.co.flash.openapi.web.AirtimePurchaseController.airtimeService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.flashmobilecash.services.PrePaidAirtimeService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:522)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:298)
... 59 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.flashmobilecash.services.PrePaidAirtimeService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1118)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:967)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:862)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:494)
... 61 more
HTTP Invoker代理在Java配置中配置:
@Configuration
public class HttpServicesConfig {
@Value("${flashtp.ipaddress}")
private String ipAddress;
@Value("${flashtp.httpservices.port}")
private String port;
@Bean
public CloseableHttpClient httpClient() {
HttpClientBuilder builder = HttpClientBuilder.create();
builder.setMaxConnPerRoute(60);
builder.setMaxConnTotal(60);
RequestConfig requestConfig =
RequestConfig.custom().setConnectTimeout(10000)
.setConnectionRequestTimeout(10000)
.setSocketTimeout(10000)
.build();
builder.setDefaultRequestConfig(requestConfig);
CloseableHttpClient httpClient = builder.build();
return httpClient;
}
@Bean
public HttpComponentsHttpInvokerRequestExecutor httpClientExecutor() {
HttpComponentsHttpInvokerRequestExecutor executor =
new HttpComponentsHttpInvokerRequestExecutor();
executor.setConnectTimeout(10000);
executor.setHttpClient(httpClient());
return executor;
}
.....
@Bean
public HttpInvokerProxyFactoryBean prePaidAirtimeService() {
HttpInvokerProxyFactoryBean b = new HttpInvokerProxyFactoryBean();
b.setServiceInterface(PrePaidAirtimeService.class);
b.setServiceUrl(
"http://" + ipAddress + ":" + port +
"/flash-http-services/remoting/prePaidAirtimeService");
b.setHttpInvokerRequestExecutor(httpClientExecutor());
return b;
}
}
然后将此配置导入主应用程序配置:
@Configuration
@Import(HttpServicesConfig.class)
@ComponentScan(basePackages = { "za.co.flash.openapi" })
@EnableAutoConfiguration(exclude = {
SecurityAutoConfiguration.class,
HibernateJpaAutoConfiguration.class
})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
我不确定我做错了什么。
此致
答案 0 :(得分:1)
这种在Spring Java配置中配置HTTP Invoker的方法解决了这个问题:
@Bean
public PrePaidAirtimeService prePaidAirtimeService() {
HttpInvokerProxyFactoryBean f = new HttpInvokerProxyFactoryBean();
f.setServiceInterface(PrePaidAirtimeService.class);
f.setServiceUrl(
"http://" + ipAddress + ":" + port +
"/flash-http-services/remoting/prePaidAirtimeService");
f.setHttpInvokerRequestExecutor(httpClientExecutor());
f.afterPropertiesSet();
return (PrePaidAirtimeService) f.getObject();
}
谢谢@M。 Deinum指出我正确的方向。