highlight: arduino-light
8.CglibAopProxy#getProxy(java.lang.ClassLoader)
```java @Override public Object getProxy(@Nullable ClassLoader classLoader){ try { //从proxyFactory中获取代理类的class Class> rootClass = this.advised.getTargetClass();
Class<?> proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
validateClassIfNecessary(proxySuperClass, classLoader); Enhancer enhancer = createEnhancer(); if (classLoader != null) { enhancer.setClassLoader(classLoader); if (classLoader instanceof SmartClassLoader && ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) { enhancer.setUseCache(false); } } enhancer.setSuperclass(proxySuperClass); enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised)); enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE); enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy (classLoader)); //最重要的是DynamicAdvisedInterceptor 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); return createProxyClassAndInstance(enhancer, callbacks); } catch (CodeGenerationException | IllegalArgumentException ex) { throw new AopConfigException(); } catch (Throwable ex) { throw new AopConfigException("Unexpected AOP exception", ex); } } ```
0.获取代理类class
java //从proxyFactory中获取被代理类的class Class<?> rootClass = this.advised.getTargetClass();
我们可以看到,上边的代码,其实就是获取了目标类的class对象,说白了就是被代理类的class对象
那么获取这个对象干嘛呢?
cglib是采用继承目标类,重写父类方法的形式实现的动态代理,所以当然需要指定代理类的父类了
1.创建enhancer,设置代理类为父类
java Enhancer enhancer = createEnhancer(); if (classLoader != null) { enhancer.setClassLoader(classLoader); if (classLoader instanceof SmartClassLoader && ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) { enhancer.setUseCache(false); } } enhancer.setSuperclass(proxySuperClass); enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised)); enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE); enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
构造了一个Enhancer,然后为Enhancer设置了各种属性,比如通过enhancer.setSuperclass(proxySuperClass)这行代码,就设置了代理类要实现的父类。
3.创建DynamicAdvisedInterceptor
对于Enhancer来说,除了设置要继承的父类外,还需要设置回调,其实就是callbacks,此时我们看到上边的代码中,有一行获取回调数组的方法,就是Callback[] callbacks = getCallbacks(rootClass),我们就来看看这里是怎么来获取回调数组的吧,此时getCallbacks()代码如下:
java private Callback[] getCallbacks(Class<?> rootClass) throws Exception { // AOP回调需要用到的拦截器 //advised是我们的proxyFactory //里面封装了当前类所有可用的advisor Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised); // 省略部分代码 // 创建拦截器数组 Callback[] mainCallbacks = new Callback[] { aopInterceptor, targetInterceptor, new SerializableNoOp(), targetDispatcher, this.advisedDispatcher, new EqualsInterceptor(this.advised), new HashCodeInterceptor(this.advised) }; Callback[] callbacks; if (isStatic && isFrozen) { //省略部分代码 } else { // 设置回调拦截器数组给callbacks callbacks = mainCallbacks; } return callbacks; }
这里的代码非常简单,其实就是先创建了一个DynamicAdvisedInterceptor拦截器的实例aopInterceptor
接着手动构建了一个回调数组mainCallbacks,将一堆拦截器放入这个回调数组中,其中就包括刚才创建的aopInterceptor拦截器,最后会将回调数组mainCallbacks赋值给callbacks并返回。
而这个callbacks中的拦截器,就是cglib代理对象中的方法被调用时需要回调的拦截器,这些拦截器中,有一个极为重要的拦截器aopInterceptor,aopInterceptor的类型是DynamicAdvisedInterceptor拦截器,大家这里先有个印象,随着后边分析越来越深入,自然就知道这个拦截器为什么如此重要了。
4.拦截器中包含了固定的7个Callback
```java
/* DynamicAdvisedInterceptor封装了我们切面和事务的advisor callbacks = {Callback[7]@3006} 0 = {CglibAopProxy$DynamicAdvisedInterceptor@2967} //注意这里 1 = {CglibAopProxy$StaticUnadvisedInterceptor@2981} 2 = {CglibAopProxy$SerializableNoOp@3013} 3 = {CglibAopProxy$StaticDispatcher@2989} 4 = {CglibAopProxy$AdvisedDispatcher@2902} 5 = {CglibAopProxy$EqualsInterceptor@3014} 6 = {CglibAopProxy$HashCodeInterceptor@3015} */
/** DynamicAdvisedInterceptor是我们的aopInterceptor从中可以看到我们的advisors
使用生成的代理类proxyClass,通过newInstance()方法进一步生成了代理类的实例proxyInstance,最后将回调数组callbacks设置到代理类proxyInstance中。
到这里,cglib代理才算是真正创建成功了,此时我们知道,在回调数组callbacks中,有一个极为重要的拦截器,那就是DynamicAdvisedInterceptor,当cglib代理类实例中的方法被调用时,那么就会回调到这个拦截器DynamicAdvisedInterceptor,此时这个拦截器就会开始执行增强方法和目标方法。 DynamicAdvisedInterceptor中的advisors属性 可以发现事务在最后面 **/ ```
5.根据enhancer生成字节码,动态加载
```java @Override protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) { Class> proxyClass = enhancer.createClass(); Object proxyInstance = null;
if (objenesis.isWorthTrying()) {
try {
proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
}catch (Throwable ex) {
}
}
if (proxyInstance == null) {
// Regular instantiation via default constructor...
try {
Constructor<?> ctor = (this.constructorArgs != null ?
proxyClass.getDeclaredConstructor(this.constructorArgTypes) :
proxyClass.getDeclaredConstructor());
ReflectionUtils.makeAccessible(ctor);
proxyInstance = (this.constructorArgs != null ?
ctor.newInstance(this.constructorArgs) : ctor.newInstance());
} catch (Throwable ex) {
throw new AopConfigException();
}
}
((Factory) proxyInstance).setCallbacks(callbacks);
return proxyInstance;
} ```
我们可以看到,这里首先调用Enhancer的createClass()方法生成了代理类proxyClass
6.创建代理对象
接着使用生成的代理类proxyClass,通过newInstance()方法进一步生成了代理类的实例proxyInstance,最后将回调数组callbacks设置到代理类proxyInstance中。
到这里,cglib代理才算是真正创建成功了,此时我们知道,在回调数组callbacks中,有一个极为重要的拦截器,那就是DynamicAdvisedInterceptor,当cglib代理类实例中的方法被调用时,那么就会回调到这个拦截器DynamicAdvisedInterceptor,此时这个拦截器就会开始执行增强方法和目标方法。
7.DynamicAdvisedInterceptor#intercept
通过前边的学习,我们知道,当调用jdk代理中的方法时,会回调到JdkDynamicAopProxy的invoke()方法,那么cglib代理中的方法被调用时,会回调到哪个类的哪个方法呢?
在为cglib代理创建拦截器回调数组时,其实里边有一个极为重要的拦截器。这个极为重要的拦截器其实就是DynamicAdvisedInterceptor,这个就是cglib代理回调需要用到的拦截器,说白了就是,当cglib代理中的方法被调用时,其实就会回调到这个DynamicAdvisedInterceptor。
现在呢,我们知道会回调到DynamicAdvisedInterceptor类了,那么具体是回调这个类的哪个方法呢?
我们上节讲过,在为cglib代理创建拦截器回调数组时,其实里边有一个极为重要的拦截器,如下图:
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
现在呢,我们知道会回调到DynamicAdvisedInterceptor类了,那么具体是回调这个类的哪个方法呢?
可以看到,当时我们的核心逻辑,都放在了intercept()方法中
所以根据之前我们玩儿字节码增强器Enhancer的经验,可以知道,当cglib代理的方法被调用时,其实是会回调到DynamicAdvisedInterceptor类的intercept()方法的!
那还有啥好说的,我们来看下DynamicAdvisedInterceptor类的intercept()方法呗。
其实啊,这个DynamicAdvisedInterceptor其实是CglibAopProxy中的一个内部类。
而DynamicAdvisedInterceptor的intercept()方法,代码如下:
org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor#intercept
java @Override @Nullable 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; } target = targetSource.getTarget(); Class<?> targetClass = (target != null ? target.getClass() : null); /*** 封装chain this.advised是我们的ProxyFactory ProxyFactory封装了各种参数比如被代理类的实例以及advisors advisor中又封装了增强方法和增强方法的切面表达式。 ***/ List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); Object retVal; // Check whether we only have one InvokerInterceptor: that is, // no real advice, but just reflective invocation of the target. if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) { Object[] argsToUse =AopProxyUtils.adaptArgumentsIfNecessary(method, args); retVal = methodProxy.invoke(target, argsToUse); } else { // 创建1个CglibMethodInvocation 父类是 ReflectiveMethodInvocation //注意proceed方法的调用 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) { // Restore old proxy. AopContext.setCurrentProxy(oldProxy); } } }
8.获取拦截器链
cglib代理是如何获取拦截器链的?
那么首先就会来执行下边这块代码
``` //被代理类的实例 TargetSource targetSource = this.advised.getTargetSource(); try { //判断是否需要暴露代理类 if (this.advised.exposeProxy) { oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; }
target = targetSource.getTarget(); ```
这块代码其实很简单,就是用来获取目标类的,其实最终获取的这个目标类targetClass的值就是代理类。在分析jdk代理的invoke()方法时,也有类似的代码,非常简单。
好,获取到目标类后,我们继续往下看,此时就会看到下边这行代码
java List<Object> chain = this.advised .getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
看到上边这行代码,大家有没有觉得很熟悉?咋感觉这里获取拦截器链的代码,在分析jdk代理时见过呢?
带着这个疑问,我们点进去这个getInterceptorsAndDynamicInterceptionAdvice()方法来看下
```java @Override public List
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
//获取proxyFactory的advisors
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass
= (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
//遍历advisors
for (Advisor advisor : advisors) {
//判断类级别匹配
if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut()
.getClassFilter().matches(actualClass)) {
//方法匹配器
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
//方法签名匹配
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm)
.matches(method, actualClass, hasIntroductions);
}else {
match = mm.matches(method, actualClass);
}
//匹配通过
if (match) {
//获取拦截器
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (mm.isRuntime()) {
for (MethodInterceptor interceptor : interceptors) {
interceptorList
.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
} else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
} ```
```java @Override public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException { List interceptors = new ArrayList<>(3); //获取Advice Advice advice = advisor.getAdvice(); //判断advice的类型 是MethodInterceptor 直接加入 if (advice instanceof MethodInterceptor) { interceptors.add((MethodInterceptor) advice); }
//不是MethodInterceptor类型 使用适配器包装
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
return interceptors.toArray(new MethodInterceptor[0]);
} ```
```java
@Override @Nullable public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
AspectJAnnotation<?> aspectJAnnotation
=AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
// If we get here, we know we have an AspectJ method.
// Check that it's an AspectJ-annotated class
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: " +
"Offending method '" + candidateAdviceMethod + "' in class [" +
candidateAspectClass.getName() + "]");
}
if (logger.isDebugEnabled()) {
logger.debug("Found AspectJ method: " + candidateAdviceMethod);
}
AbstractAspectJAdvice springAdvice;
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut:
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround:
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore:
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter:
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning:
springAdvice = new AspectJAfterReturningAdvice
(candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation
= (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation
= (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
// Now to configure the advice...
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
} ```
看到上边的代码后,简直惊呆了,这个不就是我们分析jdk代理时,获取拦截器链的代码吗?
难道cglib代理在获取拦截器链时,和jdk代理调用的是同一个方法?
哈哈,同学,你猜对了,确实是这样的,cglib代理和jdk代理在获取拦截器链时,调用的确实是同一个方法,说白了就是获取拦截器链的流程是完全一模一样的!惊不惊喜意不意外?哈哈哈
那现在就好办了,之前我们分析jdk代理时,重点分析过这个获取拦截器链的流程。
在获取拦截器链时,首先会将目标方法作为缓存key,到缓存中看下对应的拦截器链存不存在,如果存在的话,那么就将拦截器链作为结果返回。
而如果缓存中不存在拦截器链的话,那么就会从ProxyFactory中获取目标类级别对应的增强,接着去遍历这些增强,遍历的时候,会先来看下目标方法所在的类和增强是否匹配,如果类级别匹配的话,那么会接着看下目标方法与切点表达式在方法参数、方法名称、方法抛出异常、方法返回值维度是否都可以精确匹配,最后将匹配上的增强收集起来。
接着就开始处理这些匹配成功的增强,简单来说,就是将这些匹配成功增强中的增强方法统一封装为拦截器,然后这些拦截器会统一放到一个拦截器集合中,而这个拦截器集合其实就是拦截器链,然后就会将这个拦截器链放到缓存中,最后会将这个拦截器链作为结果返回。
这个就是获取拦截器链的整个过程,我们简单回顾了一遍,至于里边的一些细节,我们之前都详细讲过,这里就不再赘述了。
9.执行拦截器链
cglib代理是如何执行拦截器链的?
那么获取到拦截器链之后,下一步该做什么了呢?我们继续往下看,获取拦截器之后,就要执行下边这块代码了。
``` if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}else { // 创建1个CglibMethodInvocation 父类是 ReflectiveMethodInvocation retVal = new CglibMethodInvocation (proxy, target, method, args, targetClass, chain, methodProxy) //注意proceed方法的调用 .proceed(); } retVal = processReturnType(proxy, target, method, retVal); return retVal; ```
大家可以看到,其实这里的逻辑和jdk代理的逻辑差不多,都是一样的套路。
就是先看下拦截器链chain是不是为空,如果为空的话,说明此时没有增强需要执行,那此时直接执行目标方法就完事儿了。而如果拦截器链chain不为空,那此时就需要来执行拦截器链中的增强方法了。
通过上图,可以看到,这里先通过构造方法创建了一个CglibMethodInvocation类的实例.
接着调用了这个实例的proceed()方法。
```java 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);
this.methodProxy = (Modifier.isPublic(method.getModifiers())
&&method.getDeclaringClass() != Object.class
&&!AopUtils.isEqualsMethod(method)
&&!AopUtils.isHashCodeMethod(method)
&&!AopUtils.isToStringMethod(method) ? methodProxy : null);
}
@Override
protected Object invokeJoinpoint() throws Throwable {
if (this.methodProxy != null) {
return this.methodProxy.invoke(this.target, this.arguments);
}
else {
return super.invokeJoinpoint();
}
}
} ```
CglibMethodInvocation主要依赖于父类ReflectiveMethodInvocation的构造方法完成的初始化,其中比较重要的,就是将拦截器链chain最终赋值给了成员变量interceptorsAndDynamicMethodMatchers。
在CglibMethodInvocation的实例构建完成后,下一步就要调用CglibMethodInvocation的proceed()方法。
也就是说,接下来要调用CglibMethodInvocation类的proceed()方法了,那这时候,我们来看下proceed()方法的代码呗。
其实proceed()方法关键就一行代码,那就是super.proceed(),说白了就是依赖于父类的proceed()方法完成了功能。
那么父类是谁呢?
其实我们刚刚分析过,这个父类其实就是ReflectiveMethodInvocation,那还有啥好说的,我们来看下ReflectiveMethodInvocation类中的proceed()方法呗,此时我们会看到下边的代码
java @Override @Nullable public Object proceed() throws Throwable { // We start with an index of -1 and increment early. // 初始currentInterceptorIndex为-1,每调用一次proceed就把currentInterceptorIndex+1 if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { // 当调用次数 = 拦截器个数时 // 1. 触发当前method方法 return invokeJoinpoint(); } Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // Evaluate dynamic method matcher here: static part will already have // been evaluated and found to match. 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 { // 2. 普通拦截器,直接触发拦截器invoke方法 return proceed(); } }else { // It's an interceptor, so we just invoke it: The pointcut will have // been evaluated statically before this object was constructed. return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }
这个proceed()方法,就是之前我们分析jdk代理执行拦截器链时,不断递归调用的那个proceed()方法!
只不过当时jdk代理的玩儿法是直接调用ReflectiveMethodInvocation类的proceed()方法。
在JdkDynamicAopProxy中的处理,是直接new了一个ReflectiveMethodInvocation实例,接着调用了这个实例proceed()方法。
而在这里cglib的处理,其实就是先构造了一个CglibMethodInvocation的实例,而这个CglibMethodInvocation其实是ReflectiveMethodInvocation的子类,接着会调用子类CglibMethodInvocation的proceed()。
其实在子类CglibMethodInvocation的proceed()方法中,其实还是依赖于父类ReflectiveMethodInvocation的proceed()方法完成的功能,所以cglib在执行拦截器链时,本质还是调用了ReflectiveMethodInvocation的proceed()方法,其实和jdk代理执行拦截器链是一样的套路!
后续的流程,其实就是不断的递归调用ReflectiveMethodInvocation的proceed()方法,从而将所有的拦截器串成一根链条,这样拦截器之间就会按照一定的顺序,执行各自的增强方法。
在满足递归结束的条件后,首先会执行目标方法,而执行完目标方法后,接着就会层层返回执行结果,接着其他的拦截器就会分别执行自己内部的增强方法了,执行拦截器链的整个过程