相关阅读
简介
Joinpoint
表示通用的运行时连接点;
运行时连接点是发生在静态连接点上的事件,比如方法的一次调用就是运行时连接点;可以通过getStaticPart
获取连接点的静态部分;
在拦截框架的上下文中,运行时连接点是可访问的对象(方法,构造方法,字段),即连接点的静态部分,的访问的物化,被传递给注册在静态连接点上的拦截器;
源码
public interface Joinpoint {
// 继续链中下一个拦截器
@Nullable
Object proceed() throws Throwable;
// 获取持有当前连接点静态部分的对象,比如当前调用的目标对象
// 如果可访问的对象是静态的,则返回null
@Nullable
Object getThis();
// 获取连接点的静态部分(方法,构造方法,字段等)
@Nonnull
AccessibleObject getStaticPart();
}
实现子类
public interface Joinpoint
public interface Invocation extends Joinpoint
public interface ConstructorInvocation extends Invocation
public interface MethodInvocation extends Invocation
public interface ProxyMethodInvocation extends MethodInvocation
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable
private static class CglibMethodInvocation extends ReflectiveMethodInvocation
Invocation
简介
Invocation
代表一次调用;
Invocation
可以被Interceptor
拦截;
核心代码
public interface Invocation extends Joinpoint {
// 获取方法调用的参数
@Nonnull
Object[] getArguments();
}
ConstructorInvocation
简介
ConstructorInvocation
代表构造方法的调用,在构造方法调用时提供给拦截器;
ConstructorInvocation
可以被ConstructorInterceptor
拦截;
核心代码
public interface ConstructorInvocation extends Invocation {
// 获取被调用的构造方法
@Nonnull
Constructor<?> getConstructor();
}
MethodInvocation
简介
MethodInvocation
代表方法的调用,在方法调用时提供给拦截器;
MethodInvocation
可以被MethodInterceptor
拦截;
核心代码
public interface MethodInvocation extends Invocation {
// 获取被调用的方法
@Nonnull
Method getMethod();
}
ProxyMethodInvocation
简介
ProxyMethodInvocation
支持访问通过该方法调用的代理对象;
当需要替换返回值为代理对象时,这很有用,比如方法的返回值就是目标对象本身;
核心代码
public interface ProxyMethodInvocation extends MethodInvocation {
// 获取该方法调用的代理对象
Object getProxy();
// clone自身
// 如果在proceed之前发生,则每个clone体都可以调用proceed和advice chain的剩余部分
MethodInvocation invocableClone();
// 带参的clone
// 如果在proceed之前发生,则每个clone体都可以调用proceed和advice chain的剩余部分
MethodInvocation invocableClone(Object... arguments);
// 设置用于advice chain中后续方法调用的参数
void setArguments(Object... arguments);
// 设置用户属性
void setUserAttribute(String key, @Nullable Object value);
// 获取用户设置属性
@Nullable
Object getUserAttribute(String key);
}
ProxyMethodInvocation
简介
ProxyMethodInvocation
支持访问通过该方法调用的代理对象;
当需要替换返回值为代理对象时,这很有用,比如方法的返回值就是目标对象本身;
核心代码
public interface ProxyMethodInvocation extends MethodInvocation {
// 获取该方法调用的代理对象
Object getProxy();
// clone自身
// 如果在proceed之前发生,则每个clone体都可以调用proceed和advice chain的剩余部分
MethodInvocation invocableClone();
// 带参的clone
// 如果在proceed之前发生,则每个clone体都可以调用proceed和advice chain的剩余部分
MethodInvocation invocableClone(Object... arguments);
// 设置用于advice chain中后续方法调用的参数
void setArguments(Object... arguments);
// 设置用户属性
void setUserAttribute(String key, @Nullable Object value);
// 获取用户设置属性
@Nullable
Object getUserAttribute(String key);
}
ReflectiveMethodInvocation
简介
Spring框架的MethodInvocation
实现,通过反射
调用目标对象,子类可以重写invokeJoinpoint
方法来实现其它的逻辑;
可以通过invocableClone
克隆一次方法调用来重复执行proceed
,也可以通过setUserAttribute
/getUserAttribute
绑定一些定制属性到方法调用;
核心代码
public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {
// 代理对象
protected final Object proxy;
// 目标对象
@Nullable
protected final Object target;
// 被调用的方法
protected final Method method;
// 方法参数
protected Object[] arguments;
// 目标对象类型
@Nullable
private final Class<?> targetClass;
// 用户属性
@Nullable
private Map<String, Object> userAttributes;
// Advice chain
protected final List<?> interceptorsAndDynamicMethodMatchers;
// 当前拦截器的索引
private int currentInterceptorIndex = -1;
// 构造方法
protected ReflectiveMethodInvocation(
Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments,
@Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
this.proxy = proxy;
this.target = target;
this.targetClass = targetClass;
this.method = BridgeMethodResolver.findBridgedMethod(method);
this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);
this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;
}
@Override
public final Object getProxy() {
// 返回代理对象
return this.proxy;
}
@Override
@Nullable
public final Object getThis() {
// 返回目标对象
return this.target;
}
@Override
public final AccessibleObject getStaticPart() {
// 返回调用方法
return this.method;
}
@Override
public final Method getMethod() {
return this.method;
}
@Override
public final Object[] getArguments() {
return this.arguments;
}
@Override
public void setArguments(Object... arguments) {
this.arguments = arguments;
}
@Override
@Nullable
public Object proceed() throws Throwable {
// 遍历完advice chain后,才执行连接点
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 获取当前遍历到的Advice
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Advice是InterceptorAndDynamicMethodMatcher
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
// 方法是否动态匹配
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
// 匹配则执行
return dm.interceptor.invoke(this);
}
else {
// 动态匹配失败,则跳过本次Advice,直接执行advice chain中下一个
return proceed();
}
}
else {
// Advice是Interceptor,直接调用
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
@Nullable
protected Object invokeJoinpoint() throws Throwable {
// 通过反射执行连接点
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
@Override
public MethodInvocation invocableClone() {
Object[] cloneArguments = this.arguments;
if (this.arguments.length > 0) {
// 参数有效,则也需要clone
cloneArguments = this.arguments.clone();
}
return invocableClone(cloneArguments);
}
@Override
public MethodInvocation invocableClone(Object... arguments) {
// Force initialization of the user attributes Map,
// for having a shared Map reference in the clone.
if (this.userAttributes == null) {
this.userAttributes = new HashMap<>();
}
try {
ReflectiveMethodInvocation clone = (ReflectiveMethodInvocation) clone();
// 设置独立的方法参数
clone.arguments = arguments;
return clone;
}
catch (CloneNotSupportedException ex) {
throw new IllegalStateException(
"Should be able to clone object of type [" + getClass() + "]: " + ex);
}
}
@Override
public void setUserAttribute(String key, @Nullable Object value) {
if (value != null) {
if (this.userAttributes == null) {
this.userAttributes = new HashMap<>();
}
this.userAttributes.put(key, value);
}
else {
if (this.userAttributes != null) {
this.userAttributes.remove(key);
}
}
}
@Override
@Nullable
public Object getUserAttribute(String key) {
return (this.userAttributes != null ? this.userAttributes.get(key) : null);
}
public Map<String, Object> getUserAttributes() {
if (this.userAttributes == null) {
this.userAttributes = new HashMap<>();
}
return this.userAttributes;
}
}
CglibMethodInvocation
简介
AOP代理使用的MethodInvocation
实现;
核心代码
private static class CglibMethodInvocation extends ReflectiveMethodInvocation {
// 方法代理
@Nullable
private final MethodProxy methodProxy;
// 构造方法
public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method,
Object[] arguments, @Nullable Class<?> targetClass,
List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
// 仅限非Object的public方法
this.methodProxy = (isMethodProxyCompatible(method) ? methodProxy : null);
}
@Override
@Nullable
public Object proceed() throws Throwable {
try {
// 调用父类实现
return super.proceed();
}
// 增加了异常处理
catch (RuntimeException ex) {
throw ex;
}
catch (Exception ex) {
if (ReflectionUtils.declaresException(getMethod(), ex.getClass()) ||
KotlinDetector.isKotlinType(getMethod().getDeclaringClass())) {
// Propagate original exception if declared on the target method
// (with callers expecting it). Always propagate it for Kotlin code
// since checked exceptions do not have to be explicitly declared there.
throw ex;
}
else {
// Checked exception thrown in the interceptor but not declared on the
// target method signature -> apply an UndeclaredThrowableException,
// aligned with standard JDK dynamic proxy behavior.
throw new UndeclaredThrowableException(ex);
}
}
}
@Override
protected Object invokeJoinpoint() throws Throwable {
if (this.methodProxy != null) {
try {
// 优先直接使用目标对象执行方法,比通过反射要略微提升性能
return this.methodProxy.invoke(this.target, this.arguments);
}
catch (CodeGenerationException ex) {
logFastClassGenerationFailure(this.method);
}
}
// 执行失败,则调用父类实现
return super.invokeJoinpoint();
}
static boolean isMethodProxyCompatible(Method method) {
return (Modifier.isPublic(method.getModifiers()) &&
method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method));
}
}