要点:cglib和jdk动态代理它们都是通过运行时,动态创建出来的代理对象的class,然后创建出代理对象。
不同点在于:jdk创建出的代理对象是和被代理对象平级的,因为它们都是同一个接口的实现类;cglib创建出来的代理对象是被代理对象的子类(父子关系)
代理方法的不同实现原理:jdk动态代理方法的原理是通过invock方法实现的。代理对象执行任何方法时,都会被 invock方法所拦截,然后都去执行invoke方法;cglib是通过监听执行回调,来达到动态代理方法的
代码块1:createAopProxy()
DefaultAopProxyFactory.class
/**
* Default {@link AopProxyFactory} implementation, creating either a CGLIB proxy
* or a JDK dynamic proxy.
*
* <p>Creates a CGLIB proxy if one the following is true for a given
* {@link AdvisedSupport} instance:
* <ul>
* <li>the {@code optimize} flag is set
* <li>the {@code proxyTargetClass} flag is set
* <li>no proxy interfaces have been specified
* </ul>
*
* <p>In general, specify {@code proxyTargetClass} to enforce a CGLIB proxy,
* or specify one or more interfaces to use a JDK dynamic proxy.
*
*/
//DefaultAopProxyFactory为AopProxyFactory的默认实现类, 它可以创建cglib代理或者jdk代理,
//创建cglib代理的条件:1、设置optimize这个属性 2、设置proxyTargetClass这个属性 3、被代理对象没有实现接口
//(这些设置都是在 第15讲 的图1中的proxyFactoryBean中设置的)
//通常情况下可以通过proxyTargetClass属性来设置cglib代理或者指定一个或多个接口来使用JDK动态代理。
//总结一句话:根据不同的配置信息,决定返回不同类型的代理(AopProxy)
@SuppressWarnings("serial")
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
//AdvisedSupport 是一些配置信息,来自于 第15讲的图1中的proxyFactoryBean
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
//判断是不是设置了Optimize、isProxyTargetClass属性、没有实现接口,这些判断条件在对上面这个类的介绍信息中有提到
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
//获取目标的类对象
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.");
}
//如果目标类是一个接口,则创建jdk的AopProxy。
//这种情况很少,这种情况就是对一个接口进行代理。也就是说被代理对象是一个接口。在配置文件中的体现就是第15讲的图1中的proxyFactoryBean
//中的target属性引用的Mytarget的class属性是一个接口
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
//创建cblib的AopProxy
//很简单,跟JdkDynamicAopProxy的创建差不多,也是调用一个构造方法而已,不多做介绍了
return new ObjenesisCglibAopProxy(config);
}
else {
//创建jdk的AopProxy
//很简单,调用JdkDynamicAopProxy的构造方法,把配置信息赋值给JdkDynamicAopProxy的一个成员属性
return new JdkDynamicAopProxy(config);
}
}
/**
* Determine whether the supplied {@link AdvisedSupport} has only the
* {@link org.springframework.aop.SpringProxy} interface specified
* (or no proxy interfaces specified at all).
*/
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
Class<?>[] ifcs = config.getProxiedInterfaces();
return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
}
}
代码块2:getProxy()
ProxyFactoryBean.class
/**
* Return the proxy object to expose.
* <p>The default implementation uses a {@code getProxy} call with
* the factory's bean class loader. Can be overridden to specify a
* custom class loader.
* @param aopProxy the prepared AopProxy instance to get the proxy from
* @return the proxy object to expose
* @see AopProxy#getProxy(ClassLoader)
*/
//返回要公开的代理对象,默认实现使用getProxy()调用工厂的bean类加载器。可以重写以指定自定义类装入器。
//通过准备好的AopProxy实例,来获取代理返回要公开的代理对象
protected Object getProxy(AopProxy aopProxy) {
//this.proxyClassLoader: 当前ProxyFactoryBean的类加载器
//通过AopProxy的getProxy()方法就可以创建不同的代理对象了(因为AopProxy有不同的类型)
//见 内部代码块1、内部代码块2
return aopProxy.getProxy(this.proxyClassLoader);
}
内部代码块1: getProxy()
JdkDynamicAopProxy.class
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
//获取代理对象的接口
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
//查找定义好的eqauls()和hashCode()方法,因为动态代理对eqauls()和hashCode()的处理跟其他地方有点不一样,想深入研究可以自行百度
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
//通过调用Proxy的newProxyInstance()方法创建代理对象(这里其实就是调用了,jdk的动态代理的方法,换句话说,java自带的jdk原生的动态代理就是这样)
//你会发现,jdk动态代理的第三个参数InvocationHandler变成了this,所以可以看出JdkDynamicAopProxy就是InvocationHandler的一个实现类。所以
//JdkDynamicAopProxy中一定实现了invoke()方法。因为代理对象本身并没有实现方法的代码,所有的方法的执行都是通过invoke()方法实现的。
//JdkDynamicAopProxy中的invoke()方法详细,见 第17讲->代码块1
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
内部代码块2: getProxy()
CglibAopProxy.class
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
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)) {
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...
//这个是cglib里面的一个对象
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
//给cglib的Enhancer对象设值(就像jdk动态代理时,做一些准备工作设置值一样)
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
//获取回调(这个好像很重要,cglib对目标对象方法的代理就是通过这些回调来完成的。jdk对目标对象方法的代理是通过invoke()方法实现的)
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的create()方法来创建代理对象
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);
}
}