public class TccFeignHandler implements InvocationHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(TccFeignHandler.class);
private Target<?> target;
private Map<Method, MethodHandler> handlers;
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, args);
} else {
final Tcc tcc = method.getAnnotation(Tcc.class);
if (Objects.isNull(tcc)) {
return this.handlers.get(method).invoke(args);
}
final TccTransactionContext tccTransactionContext =
TransactionContextLocal.getInstance().get();
if (Objects.nonNull(tccTransactionContext)) {
final TccTransactionManager tccTransactionManager =
SpringBeanUtils.getInstance().getBean(TccTransactionManager.class);
if (TccActionEnum.TRYING.getCode() == tccTransactionContext.getAction()) {
String confirmMethodName = tcc.confirmMethod();
if (StringUtils.isBlank(confirmMethodName)) {
confirmMethodName = method.getName();
}
String cancelMethodName = tcc.cancelMethod();
if (StringUtils.isBlank(cancelMethodName)) {
cancelMethodName = method.getName();
}
final TccPatternEnum pattern = tcc.pattern();
tccTransactionManager.getCurrentTransaction().setPattern(pattern.getCode());
final Class<?> declaringClass = method.getDeclaringClass();
TccInvocation confirmInvocation = new TccInvocation(declaringClass,
confirmMethodName,
method.getParameterTypes(), args);
TccInvocation cancelInvocation = new TccInvocation(declaringClass,
cancelMethodName,
method.getParameterTypes(), args);
final Participant participant = new Participant(
tccTransactionContext.getTransId(),
confirmInvocation,
cancelInvocation);
tccTransactionManager.enlistParticipant(participant);
}
}
return this.handlers.get(method).invoke(args);
}
}
public void setTarget(Target<?> target) {
this.target = target;
}
public void setHandlers(Map<Method, MethodHandler> handlers) {
this.handlers = handlers;
}
}