-
Notifications
You must be signed in to change notification settings - Fork 329
/
DegradeProxy.java
76 lines (64 loc) · 2.65 KB
/
DegradeProxy.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package com.github.lianjiatech.retrofit.spring.boot.degrade;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotatedElementUtils;
import com.github.lianjiatech.retrofit.spring.boot.core.RetrofitClient;
/**
* @author 陈添明
* @since 2022/4/30 2:27 下午
*/
public class DegradeProxy implements InvocationHandler {
private final Object source;
private final Object fallback;
private final FallbackFactory<?> fallbackFactory;
@SuppressWarnings("unchecked")
public static <T> T create(Object source, Class<T> retrofitInterface, ApplicationContext applicationContext) {
RetrofitClient retrofitClient =
AnnotatedElementUtils.findMergedAnnotation(retrofitInterface, RetrofitClient.class);
Class<?> fallbackClass = retrofitClient.fallback();
Object fallback = null;
if (!void.class.isAssignableFrom(fallbackClass)) {
fallback = applicationContext.getBean(fallbackClass);
}
Class<?> fallbackFactoryClass = retrofitClient.fallbackFactory();
FallbackFactory<?> fallbackFactory = null;
if (!void.class.isAssignableFrom(fallbackFactoryClass)) {
fallbackFactory = (FallbackFactory<?>)applicationContext.getBean(fallbackFactoryClass);
}
DegradeProxy degradeProxy = new DegradeProxy(source, fallback, fallbackFactory);
return (T)Proxy.newProxyInstance(retrofitInterface.getClassLoader(),
new Class<?>[] {retrofitInterface}, degradeProxy);
}
public DegradeProxy(Object source, Object fallback, FallbackFactory<?> fallbackFactory) {
this.source = source;
this.fallback = fallback;
this.fallbackFactory = fallbackFactory;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
return method.invoke(source, args);
} catch (Throwable e) {
Throwable cause = e.getCause();
// 熔断逻辑
if (cause instanceof RetrofitBlockException) {
Object fallbackObject = getFallbackObject(cause);
if (fallbackObject != null) {
return method.invoke(fallbackObject, args);
}
}
throw cause;
}
}
private Object getFallbackObject(Throwable cause) {
if (fallback != null) {
return fallback;
}
if (fallbackFactory != null) {
return fallbackFactory.create(cause);
}
return null;
}
}