项目启动异常如下
Caused by: java.lang.IllegalArgumentException: @RequestMapping annotation not allowed on @FeignClient interfacesat org.springframework.cloud.openfeign.support.SpringMvcContract.processAnnotationOnClass(SpringMvcContract.java:180)at feign.Contract$BaseContract.parseAndValidateMetadata(Contract.java:89)at org.springframework.cloud.openfeign.support.SpringMvcContract.parseAndValidateMetadata(SpringMvcContract.java:187)at feign.Contract$BaseContract.parseAndValidateMetadata(Contract.java:62)at feign.ReflectiveFeign$ParseHandlersByName.apply(ReflectiveFeign.java:151)at feign.ReflectiveFeign.newInstance(ReflectiveFeign.java:49)at feign.Feign$Builder.target(Feign.java:269)at org.springframework.cloud.openfeign.DefaultTargeter.target(DefaultTargeter.java:30)at org.springframework.cloud.openfeign.FeignClientFactoryBean.loadBalance(FeignClientFactoryBean.java:373)at org.springframework.cloud.openfeign.FeignClientFactoryBean.getTarget(FeignClientFactoryBean.java:421)at org.springframework.cloud.openfeign.FeignClientFactoryBean.getObject(FeignClientFactoryBean.java:396)at org.springframework.cloud.openfeign.FeignClientsRegistrar.lambda$registerFeignClient$0(FeignClientsRegistrar.java:235)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1249)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1191)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)... 84 common frames omitted
源码如下
org.springframework.cloud.openfeign.support.SpringMvcContract
@Overrideprotected void processAnnotationOnClass(MethodMetadata data, Class<?> clz) {RequestMapping classAnnotation = findMergedAnnotation(clz, RequestMapping.class);if (classAnnotation != null) {LOG.error("Cannot process class: " + clz.getName()+ ". @RequestMapping annotation is not allowed on @FeignClient interfaces.");throw new IllegalArgumentException("@RequestMapping annotation not allowed on @FeignClient interfaces");}}
项目之前运行没问题,考虑到这个问题是升级的问题导致的,可以通过修改 feign 的契约来实现,正好发现了一篇文章是讲这个的。
https://blog.csdn.net/qq_44734154/article/details/128624881
核心点如下
仿照 SpringMvcContract 新建一个类,例如 CustomSpringMvcContract,将 SpringMvcContract 代码全部复制过来,然后把 SpringMvcContract 对应的代码替换为 CustomSpringMvcContract,processAnnotationOnClass() 中最后的代码做一下调整
@Overrideprotected void processAnnotationOnClass(MethodMetadata data, Class<?> clz) {if (clz.getInterfaces().length == 0) {RequestMapping classAnnotation = (RequestMapping) AnnotatedElementUtils.findMergedAnnotation(clz, RequestMapping.class);if (classAnnotation != null && classAnnotation.value().length > 0) {String pathValue = Util.emptyToNull(classAnnotation.value()[0]);pathValue = this.resolve(pathValue);if (!pathValue.startsWith("/")) {pathValue = "/" + pathValue;}// 源码调整,将// data.template().insert(0, pathValue);// 替换为data.template().uri(pathValue);}}}
openfeign 的默认配置位于
org.springframework.cloud.openfeign.FeignClientsConfiguration
其中,需要将 Contract 进行覆盖即可
@Bean@ConditionalOnMissingBeanpublic Contract feignContract(ConversionService feignConversionService) {boolean decodeSlash = feignClientProperties == null || feignClientProperties.isDecodeSlash();return new SpringMvcContract(this.parameterProcessors, feignConversionService, decodeSlash);}
如下
import feign.Contract;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.convert.support.DefaultConversionService;import java.lang.invoke.MethodHandles;
import java.util.ArrayList;
import java.util.List;@Configuration(proxyBeanMethods = false)
public class CustomFeignClientsConfiguration {private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());@Autowired(required = false)private List<AnnotatedParameterProcessor> parameterProcessors = new ArrayList<>();@Bean@ConditionalOnMissingBean@Primarypublic Contract feignContract() {logger.info("feignContract");return new CustomSpringMvcContract(this.parameterProcessors, new DefaultConversionService());}
}
启动即可。