SpringCloud Alibaba Sentinel整合SpringCloud OpenFeign,启动报错。
Caused by: java.lang.AbstractMethodError: com.alibaba.cloud.sentinel.feign.SentinelContractHolder.parseAndValidatateMetadata(Ljava/lang/Class;)Ljava/util/List;at feign.ReflectiveFeign$ParseHandlersByName.apply(ReflectiveFeign.java:154)at feign.ReflectiveFeign.newInstance(ReflectiveFeign.java:52)at feign.Feign$Builder.target(Feign.java:251)at org.springframework.cloud.openfeign.HystrixTargeter.target(HystrixTargeter.java:38)at org.springframework.cloud.openfeign.FeignClientFactoryBean.loadBalance(FeignClientFactoryBean.java:242)at org.springframework.cloud.openfeign.FeignClientFactoryBean.getTarget(FeignClientFactoryBean.java:271)at org.springframework.cloud.openfeign.FeignClientFactoryBean.getObject(FeignClientFactoryBean.java:251)at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:169)... 39 common frames omitted
报错原因:
Sentinel框架SentinelContractHolder类中找不到parseAndValidatateMetadata这个方法,是因为这个方法拼写有错误,在Sentinel和OpenFeign新版本中已经修正parseAndValidateMetadata。
| 版本 | 方法名 |
| < 2.2.1.RELEASE | parseAndValidatateMetadata |
| >= 2.2.2.RELEASE | parseAndValidateMetadata |
Sentinel(2.2.1.RELEASE)中的SentinelContractHolder类调用的是新版本的OpenFeign(2.2.2.RELEASE)方法
而Spring Cloud Alibaba(2.2.1.RELEASE)引入的是旧版本的OpenFeign(2.2.1.RELEASE)方法。
两种解决办法:
1.解决版本问题
在父工程引入2.2.0.release版本,一定要在spring-cloud-dependencies前面,因为依赖从上到下有优先级。
org.springframework.cloud spring-cloud-openfeign-dependencies 2.2.0.RELEASE pom import org.springframework.cloud spring-cloud-dependencies Hoxton.SR3 pom import
2.新建一个com.alibaba.cloud.sentinel.feign.SentinelContractHolder
import feign.Contract;
import feign.MethodMetadata;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class SentinelContractHolder implements Contract {private final Contract delegate;public static final Map METADATA_MAP = new HashMap();public SentinelContractHolder(Contract delegate) {this.delegate = delegate;}@Overridepublic List parseAndValidatateMetadata(Class> targetType) {List metadatas = this.delegate.parseAndValidatateMetadata(targetType);metadatas.forEach((metadata) -> {MethodMetadata var10000 = (MethodMetadata)METADATA_MAP.put(targetType.getName() + metadata.configKey(), metadata);});return metadatas;}
}