在Spring Boot 2.1.1中覆盖默认的RestTemplate

时间:2018-12-14 08:15:59

标签: java spring spring-mvc spring-boot spring-hateoas

我正在使用Spring Boot 2.1.1,Spring Data REST,Spring HATEOAS,Hibernate。

在我的timerFinished类中,我创建了一个自定义@Configuration

RestTemplate

我在@Component中使用此restTemplate:

@Configuration
@EnableRetry
@EnableTransactionManagement
@EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware")
public class CustomConfiguration {

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplateBuilder().setConnectTimeout(httpClientConnectionTimeout)
                .setReadTimeout(httpClientReadTimeout).build();
        ObjectMapper objectMapper = new ObjectMapper();
        restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter(objectMapper));
        restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
        restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
        return restTemplate;
    }

直到Spring Boot 2.0.3一切正常,但是如果我更新到Spring 2.0.4或更高版本,当我尝试运行我的应用程序时,会遇到以下异常:

@Component
public class TenantRestClient {

    @Autowired
    private RestTemplate restTemplate;

     public Tenant register(Tenant tenant) {
     //my stuff here
     }

我试图:

  1. 在我的14/12/2018 09:09:55,442 INFO main testServerApplication:50 - Starting testServerApplication on SVILUPPO1 with PID 10612 (C:\Users\Daniele\Documents\workspaceREST2\test-server\target\classes started by Daniele in C:\Users\Daniele\Documents\workspaceREST2\test-management-server) 14/12/2018 09:09:55,448 DEBUG main testServerApplication:53 - Running with Spring Boot v2.1.1.RELEASE, Spring v5.1.3.RELEASE 14/12/2018 09:09:55,448 INFO main testServerApplication:679 - The following profiles are active: prod 14/12/2018 09:10:02,101 ERROR main TomcatStarter:62 - Error starting Tomcat context. Exception: org.springframework.beans.factory.UnsatisfiedDependencyException. Message: Error creating bean with name 'webSecurityConfiguration': Unsatisfied dependency expressed through method 'setContentNegotationStrategy' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$EnableWebMvcConfiguration': Unsatisfied dependency expressed through method 'setConfigurers' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webMvcConfiguration': Unsatisfied dependency expressed through field 'tenantRestClient'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'tenantRestClient': Unsatisfied dependency expressed through field 'restTemplate'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'restTemplate' defined in class path resource [cloud/test/server/config/CustomConfiguration.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.hateoas.config.ConverterRegisteringWebMvcConfigurer' available: expected single matching bean but found 2: org.springframework.hateoas.config.ConverterRegisteringWebMvcConfigurer#0,org.springframework.hateoas.config.ConverterRegisteringWebMvcConfigurer#1 14/12/2018 09:10:02,124 WARN main WebappClassLoaderBase:173 - The web application [ROOT] appears to have started a thread named [lettuce-eventExecutorLoop-1-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread: sun.misc.Unsafe.park(Native Method) java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078) java.util.concurrent.LinkedBlockingQueue.poll(LinkedBlockingQueue.java:467) io.netty.util.concurrent.SingleThreadEventExecutor.takeTask(SingleThreadEventExecutor.java:251) io.netty.util.concurrent.DefaultEventExecutor.run(DefaultEventExecutor.java:64) io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884) io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) java.lang.Thread.run(Thread.java:748) 14/12/2018 09:10:02,128 WARN main AnnotationConfigServletWebServerApplicationContext:554 - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.context.ApplicationContextException: Unable to start web server; nested exception is org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat 14/12/2018 09:10:02,163 ERROR main LoggingFailureAnalysisReporter:42 - *************************** APPLICATION FAILED TO START *************************** Description: Field restTemplate in cloud.test.server.rest.clients.TenantRestClient required a single bean, but 2 were found: - org.springframework.hateoas.config.ConverterRegisteringWebMvcConfigurer#0: defined in null - org.springframework.hateoas.config.ConverterRegisteringWebMvcConfigurer#1: defined in null Action: Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed Process finished with exit code 1 类中的@Qualifier上设置一个restTemplate
  2. 在我的@Configuration类中删除bean restTemplate

第一次尝试并没有改变任何东西,而后者却出现了这个奇怪的错误:

@Configuration

您是否有解决此奇怪错误的提示?而且...为什么只是更新到Spring Boot> = 2.0.4(相同的代码)会发生这种情况?

2 个答案:

答案 0 :(得分:1)

请尝试使用Spring Boot项目的application.properties中的以下属性。然后,它将允许您使用具有相同名称的自定义项覆盖现有的Bean定义。

spring.main.allow-bean-definition-overriding=true

答案 1 :(得分:0)

尝试用restTemplate注解@Primary bean。

@Bean
@Primary
public RestTemplate restTemplate() {
    RestTemplate restTemplate = new RestTemplateBuilder().setConnectTimeout(httpClientConnectionTimeout)
            .setReadTimeout(httpClientReadTimeout).build();
    ObjectMapper objectMapper = new ObjectMapper();
    restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter(objectMapper));
    restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
    restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
    return restTemplate;
}