Search in sources :

Example 1 with FallbackFactory

use of feign.hystrix.FallbackFactory 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);
}
Also used : HystrixCommandKey(com.netflix.hystrix.HystrixCommandKey) Field(java.lang.reflect.Field) MethodHandler(feign.InvocationHandlerFactory.MethodHandler) Target(feign.Target) Method(java.lang.reflect.Method) InvocationHandler(java.lang.reflect.InvocationHandler) HystrixCommandGroupKey(com.netflix.hystrix.HystrixCommandGroupKey) BeansException(org.springframework.beans.BeansException) FallbackFactory(feign.hystrix.FallbackFactory) Setter(com.netflix.hystrix.HystrixCommand.Setter) Map(java.util.Map)

Aggregations

Setter (com.netflix.hystrix.HystrixCommand.Setter)1 HystrixCommandGroupKey (com.netflix.hystrix.HystrixCommandGroupKey)1 HystrixCommandKey (com.netflix.hystrix.HystrixCommandKey)1 MethodHandler (feign.InvocationHandlerFactory.MethodHandler)1 Target (feign.Target)1 FallbackFactory (feign.hystrix.FallbackFactory)1 Field (java.lang.reflect.Field)1 InvocationHandler (java.lang.reflect.InvocationHandler)1 Method (java.lang.reflect.Method)1 Map (java.util.Map)1 BeansException (org.springframework.beans.BeansException)1