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前面,因为依赖从上到下有优先级。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-dependencies</artifactId>
<version>2.2.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
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<String, MethodMetadata> METADATA_MAP = new HashMap();
public SentinelContractHolder(Contract delegate) {
this.delegate = delegate;
}
@Override
public List<MethodMetadata> parseAndValidatateMetadata(Class<?> targetType) {
List<MethodMetadata> metadatas = this.delegate.parseAndValidatateMetadata(targetType);
metadatas.forEach((metadata) -> {
MethodMetadata var10000 = (MethodMetadata)METADATA_MAP.put(targetType.getName() + metadata.configKey(), metadata);
});
return metadatas;
}
}