JdkDynamicAopProxy与CglibAopProxy详解
https://blog.csdn.net/W85264/article/details/114835055
1. Spring AOP设计
2. JdkDynamicAopProxy与CglibAopProxy介绍
4.JdkDynamicAopProxy 拦截器链的获得与递归执行
要点: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); } }