第16讲:JdkDynamicAopProxy与CglibAopProxy详解

要点: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);
		}
	}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值