use of feign.InvocationHandlerFactory.MethodHandler in project resilience4j by resilience4j.
the class DecoratorInvocationHandlerTest method setUp.
@Before
public void setUp() throws Throwable {
target = new HardCodedTarget<TestService>(TestService.class, TestService.class.getSimpleName());
testService = new TestServiceImpl();
greetingMethod = testService.getClass().getDeclaredMethod("greeting");
feignDecorator = new TestFeignDecorator();
methodHandler = mock(MethodHandler.class);
when(methodHandler.invoke(any())).thenReturn(testService.greeting());
dispatch = new HashMap<>();
dispatch.put(greetingMethod, methodHandler);
testSubject = new DecoratorInvocationHandler(target, dispatch, feignDecorator);
}
use of feign.InvocationHandlerFactory.MethodHandler in project ByteTCC by liuyangming.
the class CompensableHystrixBeanPostProcessor method createProxiedObject.
@SuppressWarnings("unchecked")
private Object createProxiedObject(Object origin) {
InvocationHandler handler = Proxy.getInvocationHandler(origin);
final CompensableHystrixFeignHandler feignHandler = new CompensableHystrixFeignHandler();
feignHandler.setDelegate(handler);
Class<?> clazz = origin.getClass();
Class<?>[] interfaces = clazz.getInterfaces();
ClassLoader loader = clazz.getClassLoader();
try {
Field dispatchField = handler.getClass().getDeclaredField(HYSTRIX_FIELD_DISPATH);
dispatchField.setAccessible(true);
Map<Method, MethodHandler> dispatch = (Map<Method, MethodHandler>) dispatchField.get(handler);
Field setterField = handler.getClass().getDeclaredField(HYSTRIX_FIELD_SETTERS);
setterField.setAccessible(true);
Map<Method, Setter> setterMap = (Map<Method, Setter>) setterField.get(handler);
Field groupKeyField = Setter.class.getDeclaredField(HYSTRIX_SETTER_GRPKEY);
groupKeyField.setAccessible(true);
Field fallbackField = handler.getClass().getDeclaredField(HYSTRIX_FIELD_FALLBACK);
fallbackField.setAccessible(true);
Map<Method, Method> fallbackMap = (Map<Method, Method>) fallbackField.get(handler);
Field targetField = handler.getClass().getDeclaredField(HYSTRIX_FIELD_TARGET);
targetField.setAccessible(true);
Target<?> target = (Target<?>) targetField.get(handler);
Field factoryField = handler.getClass().getDeclaredField(HYSTRIX_FIELD_FACTORY);
factoryField.setAccessible(true);
FallbackFactory<?> factory = (FallbackFactory<?>) factoryField.get(handler);
if (factory != null) {
if (FallbackFactory.Default.class.isInstance(factory)) {
Field constantField = FallbackFactory.Default.class.getDeclaredField(HYSTRIX_FIELD_CONSTANT);
constantField.setAccessible(true);
Object constant = constantField.get(factory);
CompensableHystrixFallbackHandler fallback = new CompensableHystrixFallbackHandler(constant);
Object proxy = Proxy.newProxyInstance(constant.getClass().getClassLoader(), new Class<?>[] { CompensableHystrixInvocationHandler.class, target.type() }, fallback);
constantField.set(factory, proxy);
} else {
CompensableHystrixFallbackFactoryHandler factoryHandler = new CompensableHystrixFallbackFactoryHandler(factory, target.type());
FallbackFactory<?> proxy = (FallbackFactory<?>) Proxy.newProxyInstance(factory.getClass().getClassLoader(), new Class<?>[] { FallbackFactory.class }, factoryHandler);
factoryField.set(handler, proxy);
}
}
// end-if (factory != null)
HystrixCommandGroupKey hystrixCommandGroupKey = null;
for (Iterator<Map.Entry<Method, Setter>> itr = setterMap.entrySet().iterator(); hystrixCommandGroupKey == null && itr.hasNext(); ) {
Map.Entry<Method, Setter> entry = itr.next();
Setter setter = entry.getValue();
hystrixCommandGroupKey = setter == null ? hystrixCommandGroupKey : (HystrixCommandGroupKey) groupKeyField.get(setter);
}
final String commandGroupKeyName = hystrixCommandGroupKey == null ? null : hystrixCommandGroupKey.name();
HystrixCommandGroupKey groupKey = new HystrixCommandGroupKey() {
public String name() {
return commandGroupKeyName;
}
};
HystrixCommandKey commandKey = new HystrixCommandKey() {
public String name() {
return HYSTRIX_COMMAND_NAME;
}
};
CompensableHystrixMethodHandler hystrixHandler = new CompensableHystrixMethodHandler(dispatch);
hystrixHandler.setStatefully(this.statefully);
Setter setter = Setter.withGroupKey(groupKey).andCommandKey(commandKey);
Method key = CompensableHystrixInvocationHandler.class.getDeclaredMethod(HYSTRIX_INVOKER_NAME, new Class<?>[] { CompensableHystrixInvocation.class });
setterMap.put(key, setter);
dispatch.put(key, hystrixHandler);
fallbackMap.put(key, key);
} catch (Exception ex) {
throw new IllegalStateException("Error occurred!");
}
return Proxy.newProxyInstance(loader, interfaces, feignHandler);
}
use of feign.InvocationHandlerFactory.MethodHandler in project feign by OpenFeign.
the class ReflectiveFeign method newInstance.
/**
* creates an api binding to the {@code target}. As this invokes reflection, care should be taken
* to cache the result.
*/
@SuppressWarnings("unchecked")
@Override
public <T> T newInstance(Target<T> target) {
Map<String, MethodHandler> nameToHandler = targetToHandlersByName.apply(target);
Map<Method, MethodHandler> methodToHandler = new LinkedHashMap<Method, MethodHandler>();
List<DefaultMethodHandler> defaultMethodHandlers = new LinkedList<DefaultMethodHandler>();
for (Method method : target.type().getMethods()) {
if (method.getDeclaringClass() == Object.class) {
continue;
} else if (Util.isDefault(method)) {
DefaultMethodHandler handler = new DefaultMethodHandler(method);
defaultMethodHandlers.add(handler);
methodToHandler.put(method, handler);
} else {
methodToHandler.put(method, nameToHandler.get(Feign.configKey(target.type(), method)));
}
}
InvocationHandler handler = factory.create(target, methodToHandler);
T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(), new Class<?>[] { target.type() }, handler);
for (DefaultMethodHandler defaultMethodHandler : defaultMethodHandlers) {
defaultMethodHandler.bindTo(proxy);
}
return proxy;
}
use of feign.InvocationHandlerFactory.MethodHandler in project resilience4j by resilience4j.
the class DecoratorInvocationHandler method decorateMethodHandlers.
/**
* Applies the specified {@link FeignDecorator} to all specified {@link MethodHandler}s and
* returns the result as a map of {@link CheckedFunction}s. Invoking a {@link CheckedFunction}
* will therefore invoke the decorator which, in turn, may invoke the corresponding {@link
* MethodHandler}.
*
* @param dispatch a map of the methods from the feign interface to the {@link
* MethodHandler}s.
* @param invocationDecorator the {@link FeignDecorator} with which to decorate the {@link
* MethodHandler}s.
* @param target the target feign interface.
* @return a new map where the {@link MethodHandler}s are decorated with the {@link
* FeignDecorator}.
*/
private Map<Method, CheckedFunction<Object[], Object>> decorateMethodHandlers(Map<Method, MethodHandler> dispatch, FeignDecorator invocationDecorator, Target<?> target) {
final Map<Method, CheckedFunction<Object[], Object>> map = new HashMap<>();
for (final Map.Entry<Method, MethodHandler> entry : dispatch.entrySet()) {
final Method method = entry.getKey();
final MethodHandler methodHandler = entry.getValue();
if (methodHandler != null) {
CheckedFunction<Object[], Object> decorated = invocationDecorator.decorate(methodHandler::invoke, method, methodHandler, target);
map.put(method, decorated);
}
}
return map;
}
Aggregations