io.github.resilience4j.feign.DecoratorInvocationHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of resilience4j-feign Show documentation
Show all versions of resilience4j-feign Show documentation
Resilience4j is a lightweight, easy-to-use fault tolerance library designed for Java8 and functional programming
/*
*
* Copyright 2018
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*
*
*/
package io.github.resilience4j.feign;
import static feign.Util.checkNotNull;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
import feign.InvocationHandlerFactory.MethodHandler;
import feign.Target;
import io.vavr.CheckedFunction1;
/**
* An instance of {@link InvocationHandler} that uses {@link FeignDecorator}s to enhance the
* invocations of methods.
*/
class DecoratorInvocationHandler implements InvocationHandler {
private final Target> target;
private final Map> decoratedDispatch;
public DecoratorInvocationHandler(Target> target,
Map dispatch,
FeignDecorator invocationDecorator) {
this.target = checkNotNull(target, "target");
checkNotNull(dispatch, "dispatch");
this.decoratedDispatch = decorateMethodHandlers(dispatch, invocationDecorator, target);
}
/**
* Applies the specified {@link FeignDecorator} to all specified {@link MethodHandler}s and
* returns the result as a map of {@link CheckedFunction1}s. Invoking a {@link CheckedFunction1}
* 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> decorateMethodHandlers(Map dispatch,
FeignDecorator invocationDecorator, Target> target) {
final Map> map = new HashMap<>();
for (final Map.Entry entry : dispatch.entrySet()) {
final Method method = entry.getKey();
final MethodHandler methodHandler = entry.getValue();
map.put(method, invocationDecorator.decorate(methodHandler::invoke, method, methodHandler, target));
}
return map;
}
@Override
public Object invoke(final Object proxy, final Method method, final Object[] args)
throws Throwable {
switch (method.getName()) {
case "equals":
return equals(args.length > 0 ? args[0] : null);
case "hashCode":
return hashCode();
case "toString":
return toString();
default:
break;
}
return decoratedDispatch.get(method).apply(args);
}
@Override
public boolean equals(Object obj) {
Object compareTo = obj;
if (compareTo == null) {
return false;
}
if (Proxy.isProxyClass(compareTo.getClass())) {
compareTo = Proxy.getInvocationHandler(compareTo);
}
if (compareTo instanceof DecoratorInvocationHandler) {
final DecoratorInvocationHandler other = (DecoratorInvocationHandler) compareTo;
return target.equals(other.target);
}
return false;
}
@Override
public int hashCode() {
return target.hashCode();
}
@Override
public String toString() {
return target.toString();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy