spring-cloud-openfeign-core第三方包里面有FeignClientsConfiguration.class里面是包括了feign需要的bean,但里面已经定义了feignEncoder、feignDecoder,如果项目中想要定制feignEncoder、feignDecoder就会冲突报错No bean found of type interface feign.codec.Encoder for XXXapi,但项目中有自定义这两个bean。显然这种在Config类@Import另一个Config类,又重定义里里面的bean,即使另一个Config类有用到@ConditionalOnMissingBean也不行,只需要在冲突的bean上加 @Primary就能正常加载了,而且另一个Config类冲突的bean也不会加载到。
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import feign.Logger; import feign.codec.Decoder; import feign.codec.Encoder; import feign.optionals.OptionalDecoder; import io.vavr.jackson.datatype.VavrModule; import okhttp3.ConnectionPool; import org.springframework.beans.factory.ObjectFactory; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.cloud.openfeign.FeignClientsConfiguration; import org.springframework.cloud.openfeign.support.ResponseEntityDecoder; import org.springframework.cloud.openfeign.support.SpringDecoder; import org.springframework.cloud.openfeign.support.SpringEncoder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import java.util.concurrent.TimeUnit; @Import(FeignClientsConfiguration.class) @Configuration public class FeignClientConfig { @Bean public okhttp3.OkHttpClient okHttpClient(){ return new okhttp3.OkHttpClient.Builder() .readTimeout(60, TimeUnit.SECONDS) .connectTimeout(60,TimeUnit.SECONDS) .connectionPool(new ConnectionPool()) .build(); } @Bean public Logger.Level feignLoggerLevel(){ return Logger.Level.BASIC; } @Bean
@Primary public Encoder feignEncoder() { return new SpringEncoder(feignHttpMessageConverter()); } @Bean
@Primary public Decoder feignDecoder() { return new OptionalDecoder( new ResponseEntityDecoder(new SpringDecoder(feignHttpMessageConverter()))); } public ObjectFactory<HttpMessageConverters> feignHttpMessageConverter() { MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(); ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper(); objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); // Either 序列化问题 objectMapper.registerModule(new VavrModule()); jackson2HttpMessageConverter.setObjectMapper(objectMapper); return () -> new HttpMessageConverters(jackson2HttpMessageConverter); } }
/* * Copyright 2013-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.cloud.openfeign; import java.util.ArrayList; import java.util.List; import feign.Contract; import feign.Feign; import feign.Logger; import feign.QueryMapEncoder; import feign.Retryer; import feign.codec.Decoder; import feign.codec.Encoder; import feign.form.MultipartFormContentProcessor; import feign.form.spring.SpringFormEncoder; import feign.micrometer.MicrometerCapability; import feign.optionals.OptionalDecoder; import io.micrometer.core.instrument.MeterRegistry; import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.data.web.SpringDataWebProperties; import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.cloud.client.circuitbreaker.CircuitBreaker; import org.springframework.cloud.client.circuitbreaker.CircuitBreakerFactory; import org.springframework.cloud.openfeign.clientconfig.FeignClientConfigurer; import org.springframework.cloud.openfeign.support.AbstractFormWriter; import org.springframework.cloud.openfeign.support.FeignEncoderProperties; import org.springframework.cloud.openfeign.support.HttpMessageConverterCustomizer; import org.springframework.cloud.openfeign.support.PageableSpringEncoder; import org.springframework.cloud.openfeign.support.PageableSpringQueryMapEncoder; import org.springframework.cloud.openfeign.support.ResponseEntityDecoder; import org.springframework.cloud.openfeign.support.SpringDecoder; import org.springframework.cloud.openfeign.support.SpringEncoder; import org.springframework.cloud.openfeign.support.SpringMvcContract; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; import org.springframework.core.convert.ConversionService; import org.springframework.format.support.DefaultFormattingConversionService; import org.springframework.format.support.FormattingConversionService; import static feign.form.ContentType.MULTIPART; /** * @author Dave Syer * @author Venil Noronha * @author Darren Foong * @author Jonatan Ivanov * @author Olga Maciaszek-Sharma * @author Hyeonmin Park * @author Yanming Zhou */ @Configuration(proxyBeanMethods = false) public class FeignClientsConfiguration { @Autowired private ObjectFactory<HttpMessageConverters> messageConverters; @Autowired(required = false) private List<AnnotatedParameterProcessor> parameterProcessors = new ArrayList<>(); @Autowired(required = false) private List<FeignFormatterRegistrar> feignFormatterRegistrars = new ArrayList<>(); @Autowired(required = false) private Logger logger; @Autowired(required = false) private SpringDataWebProperties springDataWebProperties; @Autowired(required = false) private FeignClientProperties feignClientProperties; @Autowired(required = false) private FeignEncoderProperties encoderProperties; @Bean @ConditionalOnMissingBean public Decoder feignDecoder(ObjectProvider<HttpMessageConverterCustomizer> customizers) { return new OptionalDecoder(new ResponseEntityDecoder(new SpringDecoder(messageConverters, customizers))); } @Bean @ConditionalOnMissingBean @ConditionalOnMissingClass("org.springframework.data.domain.Pageable") public Encoder feignEncoder(ObjectProvider<AbstractFormWriter> formWriterProvider, ObjectProvider<HttpMessageConverterCustomizer> customizers) { return springEncoder(formWriterProvider, encoderProperties, customizers); } @Bean @ConditionalOnClass(name = "org.springframework.data.domain.Pageable") @ConditionalOnMissingBean public Encoder feignEncoderPageable(ObjectProvider<AbstractFormWriter> formWriterProvider, ObjectProvider<HttpMessageConverterCustomizer> customizers) { PageableSpringEncoder encoder = new PageableSpringEncoder( springEncoder(formWriterProvider, encoderProperties, customizers)); if (springDataWebProperties != null) { encoder.setPageParameter(springDataWebProperties.getPageable().getPageParameter()); encoder.setSizeParameter(springDataWebProperties.getPageable().getSizeParameter()); encoder.setSortParameter(springDataWebProperties.getSort().getSortParameter()); } return encoder; } @Bean @ConditionalOnClass(name = "org.springframework.data.domain.Pageable") @ConditionalOnMissingBean public QueryMapEncoder feignQueryMapEncoderPageable() { PageableSpringQueryMapEncoder queryMapEncoder = new PageableSpringQueryMapEncoder(); if (springDataWebProperties != null) { queryMapEncoder.setPageParameter(springDataWebProperties.getPageable().getPageParameter()); queryMapEncoder.setSizeParameter(springDataWebProperties.getPageable().getSizeParameter()); queryMapEncoder.setSortParameter(springDataWebProperties.getSort().getSortParameter()); } return queryMapEncoder; } @Bean @ConditionalOnMissingBean public Contract feignContract(ConversionService feignConversionService) { boolean decodeSlash = feignClientProperties == null || feignClientProperties.isDecodeSlash(); return new SpringMvcContract(parameterProcessors, feignConversionService, decodeSlash); } @Bean public FormattingConversionService feignConversionService() { FormattingConversionService conversionService = new DefaultFormattingConversionService(); for (FeignFormatterRegistrar feignFormatterRegistrar : feignFormatterRegistrars) { feignFormatterRegistrar.registerFormatters(conversionService); } return conversionService; } @Bean @ConditionalOnMissingBean public Retryer feignRetryer() { return Retryer.NEVER_RETRY; } @Bean @ConditionalOnMissingBean(FeignLoggerFactory.class) public FeignLoggerFactory feignLoggerFactory() { return new DefaultFeignLoggerFactory(logger); } @Bean @ConditionalOnMissingBean(FeignClientConfigurer.class) public FeignClientConfigurer feignClientConfigurer() { return new FeignClientConfigurer() { }; } private Encoder springEncoder(ObjectProvider<AbstractFormWriter> formWriterProvider, FeignEncoderProperties encoderProperties, ObjectProvider<HttpMessageConverterCustomizer> customizers) { AbstractFormWriter formWriter = formWriterProvider.getIfAvailable(); if (formWriter != null) { return new SpringEncoder(new SpringPojoFormEncoder(formWriter), messageConverters, encoderProperties, customizers); } else { return new SpringEncoder(new SpringFormEncoder(), messageConverters, encoderProperties, customizers); } } private class SpringPojoFormEncoder extends SpringFormEncoder { SpringPojoFormEncoder(AbstractFormWriter formWriter) { super(); MultipartFormContentProcessor processor = (MultipartFormContentProcessor) getContentProcessor(MULTIPART); processor.addFirstWriter(formWriter); } } @Configuration(proxyBeanMethods = false) @Conditional(FeignCircuitBreakerDisabledConditions.class) protected static class DefaultFeignBuilderConfiguration { @Bean @Scope("prototype") @ConditionalOnMissingBean public Feign.Builder feignBuilder(Retryer retryer) { return Feign.builder().retryer(retryer); } } @Configuration(proxyBeanMethods = false) @ConditionalOnClass(CircuitBreaker.class) @ConditionalOnProperty("feign.circuitbreaker.enabled") protected static class CircuitBreakerPresentFeignBuilderConfiguration { @Bean @Scope("prototype") @ConditionalOnMissingBean({ Feign.Builder.class, CircuitBreakerFactory.class }) public Feign.Builder defaultFeignBuilder(Retryer retryer) { return Feign.builder().retryer(retryer); } @Bean @Scope("prototype") @ConditionalOnMissingBean @ConditionalOnBean(CircuitBreakerFactory.class) public Feign.Builder circuitBreakerFeignBuilder() { return FeignCircuitBreaker.builder(); } } @Configuration(proxyBeanMethods = false) @ConditionalOnBean(type = "io.micrometer.core.instrument.MeterRegistry") @ConditionalOnClass(name = "feign.micrometer.MicrometerCapability") @ConditionalOnProperty(name = "feign.metrics.enabled", matchIfMissing = true) @Conditional(FeignClientMetricsEnabledCondition.class) protected static class MetricsConfiguration { @Bean @ConditionalOnMissingBean public MicrometerCapability micrometerCapability(MeterRegistry meterRegistry) { return new MicrometerCapability(meterRegistry); } } }
标签:feign,return,springboot,new,springframework,bean,org,import,Config From: https://www.cnblogs.com/klm-kain/p/17081681.html