Spring 动态代理

动态代理两种方式
参考https://www.cnblogs.com/leifei/p/8263448.html

  1. JDK动态代理
  2. Cglib动态代理

JDK

UserManager

package org.neosoft.proxy;
public interface IUserService {
    void sayHello(String userName);
}

UserManagerImpl

package org.neosoft.proxy;
public class UserServiceImpl implements IUserService {
    @Override
    public void sayHello(String userName) {
        System.out.println("Hello:" + userName);
    }
}

JdkProxy

package org.neosoft.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class JdkProxy implements InvocationHandler {
    /**
     * 需要代理的目标对象
     */
    private Object target;

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("JDK动态代理,监听开始!");
        Object result = method.invoke(target, args);
        System.out.println("JDK动态代理,监听结束!");
        return result;
    }

    /**
     * 定义获取代理对象方法
     *
     * @param targetObject
     * @return
     */
    public Object getJDKProxy(Object targetObject) {
        //为目标对象target赋值
        this.target = targetObject;
        //JDK动态代理只能针对实现了接口的类进行代理,newProxyInstance 函数所需参数就可看出
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
                targetObject.getClass().getInterfaces(), this);
    }

}

JdkProxyTest

package org.neosoft.proxy;

import java.io.IOException;

public class JdkProxyTest {

    public static void main(String[] args) throws IOException {
        // 根目录下输出代理生成的类
        // 不同的JDK版本参数可能不一致,直接查看源码ProxyGenerator.saveGeneratedFiles即可
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        //实例化JDKProxy对象
        JdkProxy jdkProxy = new JdkProxy();
        //获取代理对象
        IUserService user = (IUserService) jdkProxy.getJDKProxy(new UserServiceImpl());
        //执行方法
        user.sayHello("jdk");

    }
}

运行后产生$Proxy0

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.sun.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import org.neosoft.proxy.IUserService;

public final class $Proxy0 extends Proxy implements IUserService {
    private static Method m1;
    private static Method m3;
    private static Method m2;
    private static Method m0;

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final void sayHello(String var1) throws  {
        try {
            super.h.invoke(this, m3, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m3 = Class.forName("org.neosoft.proxy.IUserService").getMethod("sayHello", Class.forName("java.lang.String"));
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

Cglib

package org.neosoft.proxy;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @description
 * @author: zhusy
 * @date:2021/7/16
 **/
public class CglibProxy implements MethodInterceptor {
    /**
     * 需要代理的目标对象
     */
    private Object target;

    /**
     * 重写拦截方法
     * @param obj
     * @param method
     * @param arr
     * @param proxy
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object obj, Method method, Object[] arr, MethodProxy proxy) throws Throwable {
        System.out.println("Cglib动态代理,监听开始!");
        //方法执行,参数:target 目标对象 arr参数数组
        Object invoke = method.invoke(target, arr);
        System.out.println("Cglib动态代理,监听结束!");
        return invoke;
    }

    /**
     * 定义获取代理对象方法
     * @param objectTarget
     * @return
     */
    public Object getCglibProxy(Object objectTarget){
        //为目标对象target赋值
        this.target = objectTarget;
        Enhancer enhancer = new Enhancer();
        //设置父类,因为Cglib是针对指定的类生成一个子类,所以需要指定父类
        enhancer.setSuperclass(objectTarget.getClass());
        // 设置回调
        enhancer.setCallback(this);
        //创建并返回代理对象
        Object result = enhancer.create();
        return result;
    }
}

CglibProxyTest

package org.neosoft.proxy;

import org.springframework.cglib.core.DebuggingClassWriter;

/**
 * @description
 * @author: zhusy
 * @date:2021/7/16
 **/
public class CglibProxyTest {
    public static void main(String[] args) {
        // 生成的代理类输出到文件
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "C:\\class");
        //实例化CglibProxy对象
        CglibProxy cglib = new CglibProxy();
        //获取代理对象
        IUserService user = (IUserService) cglib.getCglibProxy(new UserServiceImpl());
        //执行方法
        user.sayHello("cglib");
    }
}

UserManagerImpl$ EnhancerByCGLIB$$87eb3d37

package org.neosoft.proxy;

import java.lang.reflect.Method;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.cglib.core.Signature;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Factory;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

public class UserManagerImpl$$EnhancerByCGLIB$$87eb3d37 extends UserManagerImpl implements Factory {
  private boolean CGLIB$BOUND;
  
  public static Object CGLIB$FACTORY_DATA;
  
  private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
  
  private static final Callback[] CGLIB$STATIC_CALLBACKS;
  
  private MethodInterceptor CGLIB$CALLBACK_0;
  
  private static Object CGLIB$CALLBACK_FILTER;
  
  private static final Method CGLIB$addUser$0$Method;
  
  private static final MethodProxy CGLIB$addUser$0$Proxy;
  
  private static final Object[] CGLIB$emptyArgs;
  
  private static final Method CGLIB$delUser$1$Method;
  
  private static final MethodProxy CGLIB$delUser$1$Proxy;
  
  private static final Method CGLIB$equals$2$Method;
  
  private static final MethodProxy CGLIB$equals$2$Proxy;
  
  private static final Method CGLIB$toString$3$Method;
  
  private static final MethodProxy CGLIB$toString$3$Proxy;
  
  private static final Method CGLIB$hashCode$4$Method;
  
  private static final MethodProxy CGLIB$hashCode$4$Proxy;
  
  private static final Method CGLIB$clone$5$Method;
  
  private static final MethodProxy CGLIB$clone$5$Proxy;
  
  static void CGLIB$STATICHOOK1() {
    CGLIB$THREAD_CALLBACKS = new ThreadLocal();
    CGLIB$emptyArgs = new Object[0];
    Class clazz1 = Class.forName("org.neosoft.proxy.UserManagerImpl$$EnhancerByCGLIB$$87eb3d37");
    Class clazz2;
    CGLIB$equals$2$Method = ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods())[0];
    CGLIB$equals$2$Proxy = MethodProxy.create(clazz2, clazz1, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$2");
    CGLIB$toString$3$Method = ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods())[1];
    CGLIB$toString$3$Proxy = MethodProxy.create(clazz2, clazz1, "()Ljava/lang/String;", "toString", "CGLIB$toString$3");
    CGLIB$hashCode$4$Method = ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods())[2];
    CGLIB$hashCode$4$Proxy = MethodProxy.create(clazz2, clazz1, "()I", "hashCode", "CGLIB$hashCode$4");
    CGLIB$clone$5$Method = ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods())[3];
    CGLIB$clone$5$Proxy = MethodProxy.create(clazz2, clazz1, "()Ljava/lang/Object;", "clone", "CGLIB$clone$5");
    ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods());
    CGLIB$addUser$0$Method = ReflectUtils.findMethods(new String[] { "addUser", "(Ljava/lang/String;Ljava/lang/String;)V", "delUser", "(Ljava/lang/String;)V" }, (clazz2 = Class.forName("org.neosoft.proxy.UserManagerImpl")).getDeclaredMethods())[0];
    CGLIB$addUser$0$Proxy = MethodProxy.create(clazz2, clazz1, "(Ljava/lang/String;Ljava/lang/String;)V", "addUser", "CGLIB$addUser$0");
    CGLIB$delUser$1$Method = ReflectUtils.findMethods(new String[] { "addUser", "(Ljava/lang/String;Ljava/lang/String;)V", "delUser", "(Ljava/lang/String;)V" }, (clazz2 = Class.forName("org.neosoft.proxy.UserManagerImpl")).getDeclaredMethods())[1];
    CGLIB$delUser$1$Proxy = MethodProxy.create(clazz2, clazz1, "(Ljava/lang/String;)V", "delUser", "CGLIB$delUser$1");
    ReflectUtils.findMethods(new String[] { "addUser", "(Ljava/lang/String;Ljava/lang/String;)V", "delUser", "(Ljava/lang/String;)V" }, (clazz2 = Class.forName("org.neosoft.proxy.UserManagerImpl")).getDeclaredMethods());
  }
  
  final void CGLIB$addUser$0(String paramString1, String paramString2) { super.addUser(paramString1, paramString2); }
  
  public final void addUser(String paramString1, String paramString2) {
    if (this.CGLIB$CALLBACK_0 == null) {
      this.CGLIB$CALLBACK_0;
      CGLIB$BIND_CALLBACKS(this);
    } 
    if (this.CGLIB$CALLBACK_0 != null) {
      new Object[2][0] = paramString1;
      new Object[2][1] = paramString2;
      return;
    } 
    super.addUser(paramString1, paramString2);
  }
  
  final void CGLIB$delUser$1(String paramString) { super.delUser(paramString); }
  
  public final void delUser(String paramString) {
    if (this.CGLIB$CALLBACK_0 == null) {
      this.CGLIB$CALLBACK_0;
      CGLIB$BIND_CALLBACKS(this);
    } 
    if (this.CGLIB$CALLBACK_0 != null) {
      new Object[1][0] = paramString;
      return;
    } 
    super.delUser(paramString);
  }
  
  final boolean CGLIB$equals$2(Object paramObject) { return super.equals(paramObject); }
  
  public final boolean equals(Object paramObject) {
    if (this.CGLIB$CALLBACK_0 == null) {
      this.CGLIB$CALLBACK_0;
      CGLIB$BIND_CALLBACKS(this);
    } 
    if (this.CGLIB$CALLBACK_0 != null) {
      this.CGLIB$CALLBACK_0.intercept(this, CGLIB$equals$2$Method, new Object[] { paramObject }, CGLIB$equals$2$Proxy);
      return (this.CGLIB$CALLBACK_0.intercept(this, CGLIB$equals$2$Method, new Object[] { paramObject }, CGLIB$equals$2$Proxy) == null) ? false : ((Boolean)this.CGLIB$CALLBACK_0.intercept(this, CGLIB$equals$2$Method, new Object[] { paramObject }, CGLIB$equals$2$Proxy)).booleanValue();
    } 
    return super.equals(paramObject);
  }
  
  final String CGLIB$toString$3() { return super.toString(); }
  
  public final String toString() {
    if (this.CGLIB$CALLBACK_0 == null) {
      this.CGLIB$CALLBACK_0;
      CGLIB$BIND_CALLBACKS(this);
    } 
    return (this.CGLIB$CALLBACK_0 != null) ? (String)this.CGLIB$CALLBACK_0.intercept(this, CGLIB$toString$3$Method, CGLIB$emptyArgs, CGLIB$toString$3$Proxy) : super.toString();
  }
  
  final int CGLIB$hashCode$4() { return super.hashCode(); }
  
  public final int hashCode() {
    if (this.CGLIB$CALLBACK_0 == null) {
      this.CGLIB$CALLBACK_0;
      CGLIB$BIND_CALLBACKS(this);
    } 
    if (this.CGLIB$CALLBACK_0 != null) {
      this.CGLIB$CALLBACK_0.intercept(this, CGLIB$hashCode$4$Method, CGLIB$emptyArgs, CGLIB$hashCode$4$Proxy);
      return (this.CGLIB$CALLBACK_0.intercept(this, CGLIB$hashCode$4$Method, CGLIB$emptyArgs, CGLIB$hashCode$4$Proxy) == null) ? 0 : ((Number)this.CGLIB$CALLBACK_0.intercept(this, CGLIB$hashCode$4$Method, CGLIB$emptyArgs, CGLIB$hashCode$4$Proxy)).intValue();
    } 
    return super.hashCode();
  }
  
  final Object CGLIB$clone$5() throws CloneNotSupportedException { return super.clone(); }
  
  protected final Object clone() throws CloneNotSupportedException {
    if (this.CGLIB$CALLBACK_0 == null) {
      this.CGLIB$CALLBACK_0;
      CGLIB$BIND_CALLBACKS(this);
    } 
    return (this.CGLIB$CALLBACK_0 != null) ? this.CGLIB$CALLBACK_0.intercept(this, CGLIB$clone$5$Method, CGLIB$emptyArgs, CGLIB$clone$5$Proxy) : super.clone();
  }
  
  public static MethodProxy CGLIB$findMethodProxy(Signature paramSignature) { // Byte code:
    //   0: aload_0
    //   1: invokevirtual toString : ()Ljava/lang/String;
    //   4: dup
    //   5: invokevirtual hashCode : ()I
    //   8: lookupswitch default -> 140, -508378822 -> 68, 1728090441 -> 80, 1826985398 -> 92, 1913648695 -> 104, 1917756541 -> 116, 1984935277 -> 128
    //   68: ldc 'clone()Ljava/lang/Object;'
    //   70: invokevirtual equals : (Ljava/lang/Object;)Z
    //   73: ifeq -> 141
    //   76: getstatic org/neosoft/proxy/UserManagerImpl$$EnhancerByCGLIB$$87eb3d37.CGLIB$clone$5$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
    //   79: areturn
    //   80: ldc 'delUser(Ljava/lang/String;)V'
    //   82: invokevirtual equals : (Ljava/lang/Object;)Z
    //   85: ifeq -> 141
    //   88: getstatic org/neosoft/proxy/UserManagerImpl$$EnhancerByCGLIB$$87eb3d37.CGLIB$delUser$1$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
    //   91: areturn
    //   92: ldc 'equals(Ljava/lang/Object;)Z'
    //   94: invokevirtual equals : (Ljava/lang/Object;)Z
    //   97: ifeq -> 141
    //   100: getstatic org/neosoft/proxy/UserManagerImpl$$EnhancerByCGLIB$$87eb3d37.CGLIB$equals$2$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
    //   103: areturn
    //   104: ldc 'toString()Ljava/lang/String;'
    //   106: invokevirtual equals : (Ljava/lang/Object;)Z
    //   109: ifeq -> 141
    //   112: getstatic org/neosoft/proxy/UserManagerImpl$$EnhancerByCGLIB$$87eb3d37.CGLIB$toString$3$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
    //   115: areturn
    //   116: ldc 'addUser(Ljava/lang/String;Ljava/lang/String;)V'
    //   118: invokevirtual equals : (Ljava/lang/Object;)Z
    //   121: ifeq -> 141
    //   124: getstatic org/neosoft/proxy/UserManagerImpl$$EnhancerByCGLIB$$87eb3d37.CGLIB$addUser$0$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
    //   127: areturn
    //   128: ldc 'hashCode()I'
    //   130: invokevirtual equals : (Ljava/lang/Object;)Z
    //   133: ifeq -> 141
    //   136: getstatic org/neosoft/proxy/UserManagerImpl$$EnhancerByCGLIB$$87eb3d37.CGLIB$hashCode$4$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
    //   139: areturn
    //   140: pop
    //   141: aconst_null
    //   142: areturn }
  
  public UserManagerImpl$$EnhancerByCGLIB$$87eb3d37() { CGLIB$BIND_CALLBACKS(this); }
  
  public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] paramArrayOfCallback) { CGLIB$THREAD_CALLBACKS.set(paramArrayOfCallback); }
  
  public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] paramArrayOfCallback) { CGLIB$STATIC_CALLBACKS = paramArrayOfCallback; }
  
  private static final void CGLIB$BIND_CALLBACKS(Object paramObject) {
    UserManagerImpl$$EnhancerByCGLIB$$87eb3d37 userManagerImpl$$EnhancerByCGLIB$$87eb3d37 = (UserManagerImpl$$EnhancerByCGLIB$$87eb3d37)paramObject;
    if (!userManagerImpl$$EnhancerByCGLIB$$87eb3d37.CGLIB$BOUND) {
      userManagerImpl$$EnhancerByCGLIB$$87eb3d37.CGLIB$BOUND = true;
      if (CGLIB$THREAD_CALLBACKS.get() == null) {
        CGLIB$THREAD_CALLBACKS.get();
        if (CGLIB$STATIC_CALLBACKS == null) {
          CGLIB$STATIC_CALLBACKS;
          return;
        } 
      } 
      userManagerImpl$$EnhancerByCGLIB$$87eb3d37.CGLIB$CALLBACK_0 = (MethodInterceptor)(Callback[])CGLIB$THREAD_CALLBACKS.get()[0];
    } 
  }
  
  public Object newInstance(Callback[] paramArrayOfCallback) {
    CGLIB$SET_THREAD_CALLBACKS(paramArrayOfCallback);
    CGLIB$SET_THREAD_CALLBACKS(null);
    return new UserManagerImpl$$EnhancerByCGLIB$$87eb3d37();
  }
  
  public Object newInstance(Callback paramCallback) {
    CGLIB$SET_THREAD_CALLBACKS(new Callback[] { paramCallback });
    CGLIB$SET_THREAD_CALLBACKS(null);
    return new UserManagerImpl$$EnhancerByCGLIB$$87eb3d37();
  }
  
  public Object newInstance(Class[] paramArrayOfClass, Object[] paramArrayOfObject, Callback[] paramArrayOfCallback) { // Byte code:
    //   0: aload_3
    //   1: invokestatic CGLIB$SET_THREAD_CALLBACKS : ([Lorg/springframework/cglib/proxy/Callback;)V
    //   4: new org/neosoft/proxy/UserManagerImpl$$EnhancerByCGLIB$$87eb3d37
    //   7: dup
    //   8: aload_1
    //   9: dup
    //   10: arraylength
    //   11: tableswitch default -> 35, 0 -> 28
    //   28: pop
    //   29: invokespecial <init> : ()V
    //   32: goto -> 49
    //   35: goto -> 38
    //   38: pop
    //   39: new java/lang/IllegalArgumentException
    //   42: dup
    //   43: ldc 'Constructor not found'
    //   45: invokespecial <init> : (Ljava/lang/String;)V
    //   48: athrow
    //   49: aconst_null
    //   50: invokestatic CGLIB$SET_THREAD_CALLBACKS : ([Lorg/springframework/cglib/proxy/Callback;)V
    //   53: areturn }
  
  public Callback getCallback(int paramInt) {
    CGLIB$BIND_CALLBACKS(this);
    switch (paramInt) {
      case 0:
      
    } 
    this.CGLIB$CALLBACK_0;
    return null;
  }
  
  public void setCallback(int paramInt, Callback paramCallback) {
    switch (paramInt) {
      case 0:
        this.CGLIB$CALLBACK_0 = (MethodInterceptor)paramCallback;
        break;
    } 
  }
  
  public Callback[] getCallbacks() {
    CGLIB$BIND_CALLBACKS(this);
    return new Callback[] { this.CGLIB$CALLBACK_0 };
  }
  
  public void setCallbacks(Callback[] paramArrayOfCallback) { this.CGLIB$CALLBACK_0 = (MethodInterceptor)paramArrayOfCallback[0]; }
  
  static  {
    CGLIB$STATICHOOK1();
  }
}

SpringAOP动态代理

接着https://www.jianshu.com/p/92e09c466176
initializeBean之后进入
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
AbstractAutoProxyCreator#postProcessAfterInitialization

@Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
        Object cacheKey = getCacheKey(beanClass, beanName);

        if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }
            if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }

        // Create proxy here if we have a custom TargetSource.
        // Suppresses unnecessary default instantiation of the target bean:
        // The TargetSource will handle target instances in a custom fashion.
        TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
        if (targetSource != null) {
            if (StringUtils.hasLength(beanName)) {
                this.targetSourcedBeans.add(beanName);
            }
                        // 获取增强器
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
            Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }

        return null;
    }

AbstractAutoProxyCreator#wrapIfNecessary

创建代理类

AbstractAutoProxyCreator#createProxy

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
            @Nullable Object[] specificInterceptors, TargetSource targetSource) {

        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
        }

        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);

        if (!proxyFactory.isProxyTargetClass()) {
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }

        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        proxyFactory.addAdvisors(advisors);
        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);

        proxyFactory.setFrozen(this.freezeProxy);
        if (advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }

        // Use original ClassLoader if bean class not locally loaded in overriding class loader
        ClassLoader classLoader = getProxyClassLoader();
        if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
            classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
        }
        //  生成动态代理对象
        return proxyFactory.getProxy(classLoader);
    }

ProxyFactory#getProxy(java.lang.ClassLoader)
ProxyCreatorSupport#createAopProxy
DefaultAopProxyFactory#createAopProxy
选择JdkDynamicAopProxy还是ObjenesisCglibAopProxy代理

@Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        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.");
            }
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                return new JdkDynamicAopProxy(config);
            }
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            return new JdkDynamicAopProxy(config);
        }
    }

CglibAopProxy#getProxy(java.lang.ClassLoader)

@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 (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);
                }
            }
            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);
        }
    }

ObjenesisCglibAopProxy#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.create(),保持一致。

// cglibProxy
public Object getCglibProxy(Object objectTarget){
        //为目标对象target赋值
        this.target = objectTarget;
        Enhancer enhancer = new Enhancer();
        //设置父类,因为Cglib是针对指定的类生成一个子类,所以需要指定父类
        enhancer.setSuperclass(objectTarget.getClass());
        // 设置回调
        enhancer.setCallback(this);
        //创建并返回代理对象
        Object result = enhancer.create();
        return result;
    }
//jdkProxy
public Object getJDKProxy(Object targetObject) {
        //为目标对象target赋值
        this.target = targetObject;
        //JDK动态代理只能针对实现了接口的类进行代理,newProxyInstance 函数所需参数就可看出
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
                targetObject.getClass().getInterfaces(), this);
    }

下面看JDK
JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)
与上面的测试代码也一致Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);

@Override
    public Object getProxy(@Nullable ClassLoader classLoader) {
        if (logger.isTraceEnabled()) {
            logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
        }
        return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
    }

核心类图:


spring动态代理核心类图.png

创建的流程图


spring动态代理创建流程图.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。