MvcUriComponentsBuilder 和 ControllerMethodInvocationInterceptor的解读
ControllerMethodInvocationInterceptor实现了CGLIB的MethodInterceptor,所以是CGLIB动态代理的方法拦截器,从命名来看是对Controller的方法做了争强。同时也实现了org.aopalliance.intercept.MethodInterceptor
private static class ControllerMethodInvocationInterceptor implements MethodInterceptor, org.aopalliance.intercept.MethodInterceptor, MvcUriComponentsBuilder.MethodInvocationInfo {
private final Class<?> controllerType;
@Nullable
private Method controllerMethod;
@Nullable
private Object[] argumentValues;
ControllerMethodInvocationInterceptor(Class<?> controllerType) {
this.controllerType = controllerType;
}
@Nullable
public Object intercept(Object obj, Method method, Object[] args, @Nullable MethodProxy proxy) {
if (method.getName().equals("getControllerType")) {
return this.controllerType;
} else if (method.getName().equals("getControllerMethod")) {
return this.controllerMethod;
} else if (method.getName().equals("getArgumentValues")) {
return this.argumentValues;
} else if (ReflectionUtils.isObjectMethod(method)) {
return ReflectionUtils.invokeMethod(method, obj, args);
} else {
this.controllerMethod = method;
this.argumentValues = args;
Class returnType = method.getReturnType();
try {
return returnType == Void.TYPE ? null : returnType.cast(initProxy(returnType, this));
} catch (Throwable var7) {
throw new IllegalStateException("Failed to create proxy for controller method return type: " + method, var7);
}
}
}
@Nullable
public Object invoke(MethodInvocation inv) throws Throwable {
return this.intercept(inv.getThis(), inv.getMethod(), inv.getArguments(), (MethodProxy)null);
}
public Class<?> getControllerType() {
return this.controllerType;
}
public Method getControllerMethod() {
Assert.state(this.controllerMethod != null, "Not initialized yet");
return this.controllerMethod;
}
public Object[] getArgumentValues() {
Assert.state(this.argumentValues != null, "Not initialized yet");
return this.argumentValues;
}
private static <T> T initProxy(Class<?> controllerType, @Nullable MvcUriComponentsBuilder.ControllerMethodInvocationInterceptor interceptor) {
interceptor = interceptor != null ? interceptor : new MvcUriComponentsBuilder.ControllerMethodInvocationInterceptor(controllerType);
if (controllerType == Object.class) {
return interceptor;
} else if (controllerType.isInterface()) {
ProxyFactory factory = new ProxyFactory(EmptyTargetSource.INSTANCE);
factory.addInterface(controllerType);
factory.addInterface(MvcUriComponentsBuilder.MethodInvocationInfo.class);
factory.addAdvice(interceptor);
return factory.getProxy();
} else {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(controllerType);
enhancer.setInterfaces(new Class[]{MvcUriComponentsBuilder.MethodInvocationInfo.class});
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setCallbackType(MethodInterceptor.class);
Class<?> proxyClass = enhancer.createClass();
Object proxy = null;
if (MvcUriComponentsBuilder.objenesis.isWorthTrying()) {
try {
proxy = MvcUriComponentsBuilder.objenesis.newInstance(proxyClass, enhancer.getUseCache());
} catch (ObjenesisException var7) {
MvcUriComponentsBuilder.logger.debug("Failed to create controller proxy, falling back on default constructor", var7);
}
}
if (proxy == null) {
try {
proxy = ReflectionUtils.accessibleConstructor(proxyClass, new Class[0]).newInstance();
} catch (Throwable var6) {
throw new IllegalStateException("Failed to create controller proxy or use default constructor", var6);
}
}
((Factory)proxy).setCallbacks(new Callback[]{interceptor});
return proxy;
}
}
}
public interface MethodInvocationInfo {
Class<?> getControllerType();
Method getControllerMethod();
Object[] getArgumentValues();
}
参考文档: