到目前为止,我们详细分析了jdk动态代理创建的整个流程,以及jdk动态代理执行的整个流程。我们知道,AOP代理其实分为jdk代理和cglib代理,接下来我们就要开始分析cglib代理,我们简单来回顾一下,我们看下边这张图:
这里最重要的其实就是config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)这行代码了。首先config.isOptimize()表示是否开启了优化策略,这个默认为false。接着是config.isProxyTargetClass(),如果这个属性为true的话,就代表是需要基于类进行代理的,说白了就是使用cglib代理的意思,而如果为false的话,那么就代表基于接口代理,也就是使用jdk代理。而最后一个条件hasNoUserSuppliedProxyInterfaces(config),简单来说,要不就是目标类没有实现接口 ,要不就是目标类实现了接口且接口类型是SpringProxy,这两种情况只要满足一种就会返回true。当这三个条件都为false时,也就是既没有开启优化策略,也没有设置基于类的代理,最后目标类实现了接口但不是SpringProxy类型的,此时就会使用jdk动态代理,如下图:
那么一旦三个条件中有一个为true,就会走到if分支里边去,但是代码执行到这里的时候,也不是说百分之百就使用cglib代理,因为这里还有一个if判断,如下图:
通过上图,可以看到,这里会再次判断下,目标类是不是本身就是一个接口或者代理类,那如果目标类本身就是一个接口或者代理类的话,这里还是会使用jdk代理的,其他情况则都会使用cglib代理了。这里简单总结一下,常见的几种情况,一般会怎么来选择代理,如下:
1、如果设置了proxyTargetClass为true,也就是设置了基于类进行代理,并且此时目标类本身既不是接口类型也不是代理类时,这个时候就会使用cglib代理
2、如果没有设置proxyTargetClass,即proxyTargetClass为false,但是此时目标类没有实现接口,此时也会使用cglib代理
3、如果目标类实现了接口,并且此时没有强制设置使用cglib代理,比如proxyTargetClass为false,这个时候就会使用jdk代理
由于我们目前既没有开启优化策略,也没有设置基于类的代理,并且目标类实现了接口但不是SpringProxy类型的,也就是说这三个条件全部为false,因此我们这里会使用jdk代理,也就是会执行这行代码,如下图:
通过刚才的分析,我们知道,按照目前配置的话,就会来创建jdk代理了,但是我们现在想来创建cglib代理,那么有没有什么办法呢?我们可以设置下proxyTargetClass属性为true,如下图:
一旦proxyTargetClass属性设置为true,那么就会执行下边这块代码,如下图:
由于我们的目标类targetClass既不是接口,也不是代理类,所以就会执行return new ObjenesisCglibAopProxy(config)这行代码来创建cglib代理了!我们来进一步看下ObjenesisCglibAopProxy类的构造方法,代码如下:
通过上图,我们可以看到,其实ObjenesisCglibAopProxy依赖父类CglibAopProxy的构造方法完成初始化,这里最关键的,其实就是将创建代理的核心配置config赋值给了成员变量advised,这样就成功构造出来了一个ObjenesisCglibAopProxy类的实例了。而之前我们也讲过,其实这个config就是一个ProxyFactory,并且这个ProxyFactory中封装了很多创建代理相关的核心属性,比如和目标类相匹配的增强,代理类需要实现的接口等等。目前为止呢,我们只是构建了一个ObjenesisCglibAopProxy对象,而不是一个真正的cglib代理,那么真正的cglib代理该怎么生成呢?我们看下边这块代码:
在创建完ObjenesisCglibAopProxy对象后,接下来就要调用getProxy(classLoader)方法来真正创建cglib对象了。其实就是调用ObjenesisCglibAopProxy类中的getProxy(classLoader)方法。而这个ObjenesisCglibAopProxy类中的getProxy(classLoader)方法,是从父类CglibAopProxy继承过来的,如下图:
我们到CglibAopProxy类的getProxy(classLoader)方法代码如下:
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
// 获取目标类,就是com.younger.springcloud.service.impl.UserServiceImpl
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
// 设置代理类要继承的父类,proxySuperClass 其实就是 com.younger.springcloud.service.impl.UserServiceImpl
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
// 获取回调数组
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
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);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
首先就是执行下边这块代码:
上边的代码,其实就是获取了目标类的class对象,说白了就是UserServiceImpl类的class对象。cglib是采用继承目标类,重写父类方法的形式实现的动态代理,所以当然需要指定代理类的父类了。获取到要继承的目标类后,我们接着往下看,此时会看到下边的代码:
通过上边的代码,我们可以看到,其实这里就是构造了一个Enhancer,然后为Enhancer设置了各种属性,比如通过enhancer.setSuperclass(proxySuperClass)这行代码,就设置了代理类要实现的父类。我们知道,对于Enhancer来说,除了设置要继承的父类外,还需要设置回调,其实就是callbacks,此时我们看到上边的代码中,有一行获取回调数组的方法,就是Callback[] callbacks = getCallbacks(rootClass),我们就来看看这里是怎么来获取回调数组的吧,此时getCallbacks()代码如下:
private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
// Parameters used for optimization choices...
boolean exposeProxy = this.advised.isExposeProxy();
boolean isFrozen = this.advised.isFrozen();
boolean isStatic = this.advised.getTargetSource().isStatic();
// Choose an "aop" interceptor (used for AOP calls).
// AOP回调需要调用到的拦截器
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
// Choose a "straight to target" interceptor. (used for calls that are
// unadvised but can return this). May be required to expose the proxy.
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()));
}
// Choose a "direct to target" dispatcher (used for
// unadvised calls to static targets that cannot return this).
Callback targetDispatcher = (isStatic ?
new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp());
// 创建拦截器数组
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;
// If the target is a static one and the advice chain is frozen,
// then we can make some optimizations by sending the AOP calls
// direct to the target using the fixed chain for that method.
if (isStatic && isFrozen) {
Method[] methods = rootClass.getMethods();
Callback[] fixedCallbacks = new Callback[methods.length];
this.fixedInterceptorMap = new HashMap<>(methods.length);
// TODO: small memory optimization here (can skip creation for methods with no advice)
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);
}
// Now copy both the callbacks from mainCallbacks
// and fixedCallbacks into the callbacks array.
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
callbacks = mainCallbacks;
}
return callbacks;
}
可以看到,这里就是先创建了一个DynamicAdvisedInterceptor拦截器的实例aopInterceptor。接着手动构建了一个回调数组mainCallbacks,将一堆拦截器放入这个回调数组中,其中就包括刚才创建的aopInterceptor拦截器,最后会将回调数组mainCallbacks赋值给callbacks并返回。而这个callbacks中的拦截器,就是cglib代理对象中的方法被调用时需要回调的拦截器,这些拦截器中,有一个极为重要的拦截器,那就是DynamicAdvisedInterceptor拦截器了。获取到回调数组之后,创建cglib代理的准备工作就完成了,此时就会执行下边这行代码:
我们到createProxyClassAndInstance方法中看下:
@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) {
logger.debug("Unable to instantiate proxy using Objenesis, " +
"falling back to regular proxy construction", 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("Unable to instantiate proxy using Objenesis, " +
"and regular proxy instantiation via default constructor fails as well", ex);
}
}
// 设置回调
((Factory) proxyInstance).setCallbacks(callbacks);
return proxyInstance;
}
我们可以看到,这里首先调用Enhancer的createClass()方法生成了代理类proxyClass,接着使用生成的代理类proxyClass,通过newInstance()方法进一步生成了代理类的实例proxyInstance,最后将回调数组callbacks设置到代理类proxyInstance中。到这里,cglib代理才算是真正创建成功了,此时我们知道,在回调数组callbacks中,有一个极为重要的拦截器,那就是DynamicAdvisedInterceptor,当cglib代理类实例中的方法被调用时,那么就会回调到这个拦截器DynamicAdvisedInterceptor,此时这个拦截器就会开始执行增强方法和目标方法。而且这个DynamicAdvisedInterceptor其实是CglibAopProxy中的一个内部类,而DynamicAdvisedInterceptor的intercept()方法,代码如下:
@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) {
// Make invocation available if necessary.
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();
// 获取目标类,其实就是 com.younger.springcloud.service.impl.UserServiceImpl
Class<?> targetClass = (target != null ? target.getClass() : null);
// 获取拦截器链
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())) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
// 直接调用目标方法
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// We need to create a method invocation...
// 现将拦截器包装到 CglibMethodInvocation中,然后在调用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);
}
}
}
首先就会来执行下边这块代码,如下图:
通过上图,可以看到,就是用来获取目标类的,其实最终获取的这个目标类targetClass的值就是UserServiceImpl,在分析jdk代理的invoke()方法时,也有类似的代码。获取到目标类后,我们继续往下看,此时就会看到下边这行代码,如下图:
主要还是调用getInterceptorsAndDynamicInterceptionAdvice方法获取拦截器链,这个和JDk的是一样的。我们继续往下看,获取拦截器之后,就要执行下边这块代码了,如下图:
可以看到,这里的逻辑和jdk代理的逻辑差不多。就是先看下拦截器链chain是不是为空,如果为空的话,说明此时没有增强需要执行,那此时直接执行目标方法。而如果拦截器链chain不为空,那此时就需要来执行拦截器链中的增强方法了,此时就会执行下边这行代码了,如下图:
可以看到,这里先通过构造方法创建了一个CglibMethodInvocation类的实例,接着调用了这个实例的proceed()方法。我们先来看下这个构造方法都做了什么,代码如下:
我们可以看到,其实CglibMethodInvocation主要依赖于父类ReflectiveMethodInvocation的构造方法完成的初始化,其中比较重要的,就是将拦截器链chain最终赋值给了成员变量interceptorsAndDynamicMethodMatchers。在CglibMethodInvocation的实例构建完成后,下一步就要调用CglibMethodInvocation的proceed()方法了,如下图:
接下来要调用CglibMethodInvocation类的proceed()方法了,那这时候,我们来看下proceed()方法的代码呗,如下图:
大家可以看到,其实proceed()方法关键就一行代码,那就是super.proceed(),说白了就是依赖于父类的proceed()方法完成了功能。其实在子类CglibMethodInvocation的proceed()方法中,其实还是依赖于父类ReflectiveMethodInvocation的proceed()方法完成的功能,所以cglib在执行拦截器链时,本质还是调用了ReflectiveMethodInvocation的proceed()方法,其实和jdk代理执行拦截器链是一样的。最后当拦截器链执行完成后,对拦截器链的返回值,做简单处理后,直接作为结果进行返回,如下图:
到这里为止,cglib代理的执行流程就结束了,可以看到,其实cglib代理在执行时,核心的两大流程,即获取拦截器链和执行拦截器链,其实和之前分析jdk代理的流程是一样的。
完善AOP代理的执行流程图: