🎉 优化SentinelFeign实现逻辑,适配最新版API

This commit is contained in:
smallchill 2021-01-31 20:41:24 +08:00
parent 40a2261911
commit 60f27fe09a
2 changed files with 16 additions and 24 deletions

View File

@ -24,12 +24,13 @@ import lombok.SneakyThrows;
import org.springblade.core.cloud.sentinel.BladeSentinelInvocationHandler; import org.springblade.core.cloud.sentinel.BladeSentinelInvocationHandler;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.cloud.openfeign.FallbackFactory; import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.FeignContext; import org.springframework.cloud.openfeign.FeignContext;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationContextAware;
import org.springframework.util.ReflectionUtils; import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Map; import java.util.Map;
@ -46,8 +47,7 @@ public class BladeFeignSentinel {
return new Builder(); return new Builder();
} }
public static final class Builder extends Feign.Builder public static final class Builder extends Feign.Builder implements ApplicationContextAware {
implements ApplicationContextAware {
private Contract contract = new Contract.Default(); private Contract contract = new Contract.Default();
private ApplicationContext applicationContext; private ApplicationContext applicationContext;
private FeignContext feignContext; private FeignContext feignContext;
@ -69,23 +69,26 @@ public class BladeFeignSentinel {
super.invocationHandlerFactory(new InvocationHandlerFactory() { super.invocationHandlerFactory(new InvocationHandlerFactory() {
@SneakyThrows @SneakyThrows
@Override @Override
public InvocationHandler create(Target target, public InvocationHandler create(Target target, Map<Method, MethodHandler> dispatch) {
Map<Method, MethodHandler> dispatch) { // 注解取值以避免循环依赖的问题
Object feignClientFactoryBean = Builder.this.applicationContext.getBean("&" + target.type().getName()); FeignClient feignClient = AnnotationUtils.findAnnotation(target.type(), FeignClient.class);
Class fallback = feignClient.fallback();
Class fallbackFactory = feignClient.fallbackFactory();
String contextId = feignClient.contextId();
Class fallback = (Class) getFieldValue(feignClientFactoryBean, "fallback"); if (!StringUtils.hasText(contextId)) {
Class fallbackFactory = (Class) getFieldValue(feignClientFactoryBean, "fallbackFactory"); contextId = feignClient.name();
String name = (String) getFieldValue(feignClientFactoryBean, "name"); }
Object fallbackInstance; Object fallbackInstance;
FallbackFactory fallbackFactoryInstance; FallbackFactory fallbackFactoryInstance;
// 判断fallback类型 // 判断fallback类型
if (void.class != fallback) { if (void.class != fallback) {
fallbackInstance = getFromContext(name, "fallback", fallback, target.type()); fallbackInstance = getFromContext(contextId, "fallback", fallback, target.type());
return new BladeSentinelInvocationHandler(target, dispatch, new FallbackFactory.Default(fallbackInstance)); return new BladeSentinelInvocationHandler(target, dispatch, new FallbackFactory.Default(fallbackInstance));
} }
if (void.class != fallbackFactory) { if (void.class != fallbackFactory) {
fallbackFactoryInstance = (FallbackFactory) getFromContext(name, "fallbackFactory", fallbackFactory, FallbackFactory.class); fallbackFactoryInstance = (FallbackFactory) getFromContext(contextId, "fallbackFactory", fallbackFactory, FallbackFactory.class);
return new BladeSentinelInvocationHandler(target, dispatch, fallbackFactoryInstance); return new BladeSentinelInvocationHandler(target, dispatch, fallbackFactoryInstance);
} }
// 默认fallbackFactory // 默认fallbackFactory
@ -115,17 +118,6 @@ public class BladeFeignSentinel {
return super.build(); return super.build();
} }
private Object getFieldValue(Object instance, String fieldName) {
Field field = ReflectionUtils.findField(instance.getClass(), fieldName);
field.setAccessible(true);
try {
return field.get(instance);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
@Override @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext; this.applicationContext = applicationContext;

View File

@ -38,7 +38,7 @@ import java.util.Map;
import static feign.Util.checkNotNull; import static feign.Util.checkNotNull;
/** /**
* 重写SentinelInvocationHandler适配最新API * 重写 {@link com.alibaba.cloud.sentinel.feign.SentinelInvocationHandler} 适配最新API
* *
* @author Chill * @author Chill
*/ */