接着上一篇 https://blog.csdn.net/convict_eva/article/details/81084833
DefaultAopProxyFactory.createAopProxy() 方法生成AopProxy 代理对象。
AopProxy 有两个实现类 JdkDynamicAopProxy,CglibAopProxy。上一篇说的是JdkDynamicAopProxy,这里说 CglibAopProxy
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
//目录对象的class
Class> targetClass = config.getTargetClass();
//没有目标对象抛出异常
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
//targetClass 是接口类,使用 JDK来生成 Proxy
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
//如果不是接口类,使用CGLIB 生成代理对象
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
CglibAopProxy 也是AopProxy 的实现,CglibAopProxy 也是 ObjenesisCglibAopProxy 父类,所以入口方法就是 ObjenesisCglibAopProxy.getProxy()方法
这个方法在CglibAopProxy 实现的
CglibAopProxy.getProxy() 源码:
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isDebugEnabled()) {
logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
}
try {
//从advised 中获取目标对象的类对象
Class> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class> proxySuperClass = rootClass;
if (ClassUtils.isCglibProxyClass(rootClass)) {
//如果目标对象已经是CGLIB 生成代理对象(就是比较类名称中有 $$ 字符串),那么就取目标对象的父类作为目标对象的类
proxySuperClass = rootClass.getSuperclass();
Class>[] additionalInterfaces = rootClass.getInterfaces();
for (Class> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
// 打印出不能代理的方法名,CGLIB 是使用继承实现的,所以final , static 的方法不能被增强
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
//创建并配置 Enhancer, Enhancer 是CGLIB 主要的操作类
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));
// 获取callbasks
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.
//通过 Enhancer 生成代理对象,并设置回调。
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);
}
}
总结:
CGLIB 通过 Enhancer 生成代理类的子类,并使用 DynamicAdvisedInterceptor 封装了增强方法
再把 DynamicAdvisedInterceptor 实现放入到callbacks 中就是通过对callbacks 的封装来完成aop的实现。
当调用代理对象的方法,会被 DynamicAdvisedInterceptor.intercept() 方法拦截。
具体怎么调用这个callbacks 的,我也不知道,猜测是生成代理类的实现有关。
CGLIB 的AOP拦截器实现:
DynamicAdvisedInterceptor 是一个 MethodInterceptor, 所以会调用他的 intercept() 方法
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();
Class> targetClass = (target != null ? target.getClass() : null);
//获取是拦截器链,和JDK中是一样的
List
总结:
从这个代码中可以看到,实现方式和jdk 动态代理是一样的,只是方法入口和MethodInvocation 实现类使用的不一样
JdkDynamicAopProxy 入口方法是动态代理的 invoke() 方法,CGLIB 使用的是 DynamicAdvisedInterceptor.intercept() 方法
JdkDynamicAopProxy 使用的MethodInvocation 是 ReflectiveMethodInvocation 子类,CGLIB 使用的是 CglibMethodInvocation。具体的实现参考上一篇就行。