The dependency implementation casts {@link Method#getGenericReturnType()}
* directly to {@link Class}. That fails for generic Feign methods such as
* {@code List}; resolve the raw type first so a proper
* empty fallback value can be returned.
*/
public class DefaultFeignFallback implements MethodInterceptor {
private static final Logger log = LoggerFactory.getLogger(DefaultFeignFallback.class);
private final Class targetType;
private final String targetName;
private final Throwable cause;
public DefaultFeignFallback(Class targetType, String targetName, Throwable cause) {
this.targetType = targetType;
this.targetName = targetName;
this.cause = cause;
}
@Override
public Object intercept(Object object, Method method, Object[] arguments, MethodProxy methodProxy) {
log.error("FunFeignFallback:[{}.{}] serviceId:[{}] message:[{}]",
targetType.getName(), method.getName(), targetName, cause == null ? null : cause.getMessage());
Type declaredReturnType = method.getGenericReturnType();
Class> returnType = rawType(declaredReturnType);
if (ResponseData.class.equals(returnType)) {
return ResponseData.builder()
.code(ErrorCodeConstants.FAIL.getValue())
.msg("系统降级,请稍后再试!")
.data(defaultValue(rawType(firstTypeArgument(declaredReturnType))))
.build();
}
return defaultValue(returnType);
}
private Type firstTypeArgument(Type type) {
if (type instanceof ParameterizedType) {
Type[] arguments = ((ParameterizedType) type).getActualTypeArguments();
if (arguments.length > 0) return arguments[0];
}
return null;
}
private Class> rawType(Type type) {
if (type instanceof Class>) return (Class>) type;
if (type instanceof ParameterizedType) return rawType(((ParameterizedType) type).getRawType());
return Object.class;
}
private Object defaultValue(Class> type) {
if (List.class.isAssignableFrom(type)) return new ArrayList