首先分享之前的所有文章 , 欢迎点赞收藏转发三连下次一定 >>>> ???
文章合集 : ? juejin.cn/post/694164…
Github : ? github.com/black-ant
一 . 前言
之前说了 AOP初始化 和 AOP 代理类的创建 , 这一篇来看一下 AOP 拦截对象的创建
二 . CglibAopProxy 代理模块
AOP 的主要代理类还是 CglibAopProxy , 所以整体流程还是以该对象为例 :
2.1 拦截对象创建的入口
在 CglibAopProxy # getProxy 主流程中 , 有几个比较重要的逻辑 , 把这几个流程整合后看一下 :
// 代码做过一定程度的省略和魔改
public Object getProxy(@Nullable ClassLoader classLoader) {
//... 省略主要逻辑
Enhancer enhancer = createEnhancer();
// rootClass => com.gang.aop.demo.service.StartService
// 获取所有的回调对象 -> PIC21001 : Callback[] 系列参数
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap,
this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
// return createProxyClassAndInstance(enhancer, callbacks);
enhancer.setInterceptDuringConstruction(false);
enhancer.setCallbacks(callbacks);
return (this.constructorArgs != null && this.constructorArgTypes != null ?
enhancer.create(this.constructorArgTypes, this.constructorArgs) :
enhancer.create());
}
复制代码
PIC21001 : Callback[] 系列参数
2.1.1 创建 Callback 对象
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// 是否为每次调用公开AOP代理
boolean exposeProxy = this.advised.isExposeProxy();
// 配置是否被冻结,并且不能进行通知更改
boolean isFrozen = this.advised.isFrozen();
// 是否所有对#getTarget()的调用都返回同一个对象
boolean isStatic = this.advised.getTargetSource().isStatic();
// 选择一个 AOP 拦截器 -> 此处创建的是 DynamicAdvisedInterceptor , 这是一个重要的类 -> 2.1.2
// advised -> PIC21101
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
// 选择性创建 StaticUnadvisedInterceptor / DynamicUnadvisedInterceptor
Callback targetInterceptor;
if (exposeProxy) {
targetInterceptor = (isStatic ?
new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource()));
}
else {
targetInterceptor = (isStatic ?
new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
new DynamicUnadvisedInterceptor(this.advised.getTargetSource()));
}
// 选择一个目标分派器
// StaticDispatcher : 静态目标的调度器 , Dispatcher比Interceptor快得多
Callback targetDispatcher = (isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
// PICPIC21102
Callback[] mainCallbacks = new Callback[] {
aopInterceptor, // for normal advice
targetInterceptor, // invoke target without considering advice, if optimized
new SerializableNoOp(), // no override for methods mapped to this
targetDispatcher, this.advisedDispatcher,
new EqualsInterceptor(this.advised),
new HashCodeInterceptor(this.advised)
};
Callback[] callbacks;
// 如果目标是静态的,并且通知链是冻结的,那么我们可以通过使用该方法的固定链将AOP调用直接发送到目标
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<>(methods.length);
for (int x = 0; x < methods.length; x++) {
Method method = methods[x];
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, rootClass);
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
this.fixedInterceptorMap.put(method, x);
}
// 从mainCallbacks和fixedCallbacks复制回调函数到callbacks数组中
callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
this.fixedInterceptorOffset = mainCallbacks.length;
}
else {
callbacks = mainCallbacks;
}
// 返回所有的回调对象
return callbacks;
}
复制代码
PIC21101 advised 中已经包含目标对象和通知面
PIC21102 : mainCallbacks 结构
扩展 : ProxyCallbackFilter 的作用
作用: CallbackFilter为方法分配回调
介绍: 该类实现了一个 Accept 方法 , 用于返回回调函数的索引
private static class ProxyCallbackFilter implements CallbackFilter {
private final AdvisedSupport advised;
private final Map<Method, Integer> fixedInterceptorMap;
private final int fixedInterceptorOffset;
}
复制代码
2.1.2 DynamicAdvisedInterceptor
作用 : 当目标是动态的或代理未被冻结时使用 , 会使用该通用的AOP回调
发起 : 从 2.1.1 中 getCallbacks 中可以看到创建流程
// 那么来看一下这个对象是如何实现方法的拦截的
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
// PRO212001 : AdvisedSupport 的作用
private final AdvisedSupport advised;
public DynamicAdvisedInterceptor(AdvisedSupport advised) {
this.advised = advised;
}
@Override
@Nullable
// proxy -> EnhancerBySpringCGLIB 代理
// method -> 实际业务方法
// args : 方法参数
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
// 当前调用的目标 ,
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 根据此配置确定给定方法的MethodInterceptor对象列表
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// 检查我们是否只有一个InvokerInterceptor (没有通知 , 只有反射调用)
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// 方法代理直接调用
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// 核心逻辑 , 此处创建了一个方法调用
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
// 处理返回类型
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// 恢复旧的代理
AopContext.setCurrentProxy(oldProxy);
}
}
}
}
// SingletonTargetSource 对象结构
public class SingletonTargetSource implements TargetSource, Serializable {
// 使用反射缓存和调用的目标
private final Object target;
}
// CglibMethodInvocation 结构
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);
// 仅对非java.lang.Object派生的公共方法使用方法代理
this.methodProxy = (Modifier.isPublic(method.getModifiers()) &&
method.getDeclaringClass() != Object.class && !AopUtils.isEqualsMethod(method) &&
!AopUtils.isHashCodeMethod(method) && !AopUtils.isToStringMethod(method) ?
methodProxy : null);
}
复制代码
可以看到 , DynamicAdvisedInterceptor 是 MethodInterceptor 的实现类 , 该接口对方法进行拦截
MethodInterceptor 的继承体系 :
PRO212001 : AdvisedSupport 的作用
作用 : AOP代理配置管理器的基类。其本身不是AOP代理,但是该类的子类通常是工厂,从这些工厂中直接获得AOP代理实例
特点 : 这个类是可序列化的 , 用于保存代理的快
public class AdvisedSupport extends ProxyConfig implements Advised {
// 通知链工厂 -> Pro
AdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();
// key 为方法缓存 , value 为 advisor 链
private transient Map<MethodCacheKey, List<Object>> methodCache;
// 代理要实现的接口
private List<Class<?>> interfaces = new ArrayList<>();
// Advisor 对象集合 , 每一个通知会包装为通知者放在该集合中
private List<Advisor> advisors = new ArrayList<>();
// 用于内部操作 , advisor 改变后会刷新该对象
private Advisor[] advisorArray = new Advisor[0];
}
// AdvisorChainFactory 的作用
复制代码
代理的核心逻辑 :
对应的方法已经在前面通过 Enhancer 进行 CGLIB 代理了 , 调用时实际调用的是 DynamicAdvisedInterceptor , 再由 DynamicAdvisedInterceptor 完成 AOP 类的调用
PS : 这里涉及到动态代理的相关概念 ,会生成 xxx$$EnhancerBySpringCGLIB$$… 的实际类 , 进行 Class 层面的调用 , 这些后面单独说说