1
0
mirror of https://gitee.com/mirrors/Spring-Cloud-Alibaba.git synced 2021-06-26 13:25:11 +08:00

sentinel unit test pass

This commit is contained in:
theonefx 2021-02-23 21:37:43 +08:00
parent e7521c02c9
commit da19750268
3 changed files with 76 additions and 38 deletions

View File

@ -77,13 +77,13 @@
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId> <artifactId>spring-cloud-commons</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId> <artifactId>spring-cloud-starter-loadbalancer</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>

View File

@ -25,16 +25,20 @@ import feign.Contract;
import feign.Feign; import feign.Feign;
import feign.InvocationHandlerFactory; import feign.InvocationHandlerFactory;
import feign.Target; import feign.Target;
//import feign.hystrix.FallbackFactory;
//import feign.hystrix.HystrixFeign;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.cloud.openfeign.FeignClientFactoryBean;
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.context.support.GenericApplicationContext;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import static org.springframework.beans.factory.BeanFactory.FACTORY_BEAN_PREFIX;
/** /**
* {@link Feign.Builder} like {@link HystrixFeign.Builder}. * {@link Feign.Builder} like {@link HystrixFeign.Builder}.
* *
@ -77,38 +81,43 @@ public final class SentinelFeign {
@Override @Override
public InvocationHandler create(Target target, public InvocationHandler create(Target target,
Map<Method, MethodHandler> dispatch) { Map<Method, MethodHandler> dispatch) {
// using reflect get fallback and fallbackFactory properties from
// FeignClientFactoryBean because FeignClientFactoryBean is a package GenericApplicationContext gctx = (GenericApplicationContext) Builder.this.applicationContext;
// level class, we can not use it in our package BeanDefinition def = gctx.getBeanDefinition(target.type().getName());
// Object feignClientFactoryBean = Builder.this.applicationContext
// .getBean("&" + target.type().getName()); /**
// * TODO
// Class fallback = (Class) getFieldValue(feignClientFactoryBean, * 由于初始化顺序发生变更这里为了避免循环依赖只能通过 BeanDefinition 的方式获得 FeignClientFactoryBean
// "fallback"); * 需要重点review
// Class fallbackFactory = (Class) getFieldValue(feignClientFactoryBean, */
// "fallbackFactory"); // FeignClientFactoryBean feignClientFactoryBean = (FeignClientFactoryBean) Builder.this.applicationContext
// String beanName = (String) getFieldValue(feignClientFactoryBean, // .getBean(FACTORY_BEAN_PREFIX + target.type().getName());
// "contextId"); FeignClientFactoryBean feignClientFactoryBean = (FeignClientFactoryBean) def.getAttribute("feignClientsRegistrarFactoryBean");
// if (!StringUtils.hasText(beanName)) {
// beanName = (String) getFieldValue(feignClientFactoryBean, "name"); Class fallback = feignClientFactoryBean.getFallback();
// } Class fallbackFactory = feignClientFactoryBean.getFallbackFactory();
// String beanName = feignClientFactoryBean.getContextId();
// Object fallbackInstance;
// FallbackFactory fallbackFactoryInstance; if (!StringUtils.hasText(beanName)) {
// // check fallback and fallbackFactory properties beanName = feignClientFactoryBean.getName();
// if (void.class != fallback) { }
// fallbackInstance = getFromContext(beanName, "fallback", fallback,
// target.type()); Object fallbackInstance;
// return new SentinelInvocationHandler(target, dispatch, FallbackFactory fallbackFactoryInstance;
// new FallbackFactory.Default(fallbackInstance)); // check fallback and fallbackFactory properties
// } if (void.class != fallback) {
// if (void.class != fallbackFactory) { fallbackInstance = getFromContext(beanName, "fallback", fallback,
// fallbackFactoryInstance = (FallbackFactory) getFromContext( target.type());
// beanName, "fallbackFactory", fallbackFactory, return new SentinelInvocationHandler(target, dispatch,
// FallbackFactory.class); new FallbackFactory.Default(fallbackInstance));
// return new SentinelInvocationHandler(target, dispatch, }
// fallbackFactoryInstance); if (void.class != fallbackFactory) {
// } fallbackFactoryInstance = (FallbackFactory) getFromContext(
beanName, "fallbackFactory", fallbackFactory,
FallbackFactory.class);
return new SentinelInvocationHandler(target, dispatch,
fallbackFactoryInstance);
}
return new SentinelInvocationHandler(target, dispatch); return new SentinelInvocationHandler(target, dispatch);
} }

View File

@ -23,6 +23,8 @@ import java.lang.reflect.Proxy;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import org.springframework.cloud.openfeign.FallbackFactory;
import com.alibaba.csp.sentinel.Entry; import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.EntryType; import com.alibaba.csp.sentinel.EntryType;
import com.alibaba.csp.sentinel.SphU; import com.alibaba.csp.sentinel.SphU;
@ -47,8 +49,18 @@ public class SentinelInvocationHandler implements InvocationHandler {
private final Map<Method, MethodHandler> dispatch; private final Map<Method, MethodHandler> dispatch;
private FallbackFactory fallbackFactory;
private Map<Method, Method> fallbackMethodMap; private Map<Method, Method> fallbackMethodMap;
SentinelInvocationHandler(Target<?> target, Map<Method, MethodHandler> dispatch,
FallbackFactory fallbackFactory) {
this.target = checkNotNull(target, "target");
this.dispatch = checkNotNull(dispatch, "dispatch");
this.fallbackFactory = fallbackFactory;
this.fallbackMethodMap = toFallbackMethod(dispatch);
}
SentinelInvocationHandler(Target<?> target, Map<Method, MethodHandler> dispatch) { SentinelInvocationHandler(Target<?> target, Map<Method, MethodHandler> dispatch) {
this.target = checkNotNull(target, "target"); this.target = checkNotNull(target, "target");
this.dispatch = checkNotNull(dispatch, "dispatch"); this.dispatch = checkNotNull(dispatch, "dispatch");
@ -100,9 +112,26 @@ public class SentinelInvocationHandler implements InvocationHandler {
if (!BlockException.isBlockException(ex)) { if (!BlockException.isBlockException(ex)) {
Tracer.trace(ex); Tracer.trace(ex);
} }
if (fallbackFactory != null) {
try {
Object fallbackResult = fallbackMethodMap.get(method)
.invoke(fallbackFactory.create(ex), args);
return fallbackResult;
}
catch (IllegalAccessException e) {
// shouldn't happen as method is public due to being an
// interface
throw new AssertionError(e);
}
catch (InvocationTargetException e) {
throw new AssertionError(e.getCause());
}
}
else {
// throw exception if fallbackFactory is null // throw exception if fallbackFactory is null
throw ex; throw ex;
} }
}
finally { finally {
if (entry != null) { if (entry != null) {
entry.exit(1, args); entry.exit(1, args);