专栏首页架构探险之道[ORM] MyBatis 中是如何运用的代理模式的?

[ORM] MyBatis 中是如何运用的代理模式的?

[ORM] MyBatis 中是如何运用的代理模式的?

简介

本文主要介绍设计模式之代理模式,并分析代理模式在 Mybatis 中是如何使用的?


静态代理动态代理源码分析深入动态代理源码小结获取更多

手机用户请横屏获取最佳阅读体验,REFERENCES中是本文参考的链接,如需要链接和更多资源,可以扫码加入『知识星球』(文末)获取长期知识分享服务。


静态代理

.

具体用户管理实现类

public class UserManagerImpl implements UserManager {
  @Override
  public void addUser(String userId, String userName) {
    System.out.println("UserManagerImpl.addUser");
  }
}

代理类

public class UserManagerImplProxy implements UserManager {
    // 目标对象
    private UserManager userManager;
    // 通过构造方法传入目标对象
    public UserManagerImplProxy(UserManager userManager){
        this.userManager=userManager;
    }
    @Override
    public void addUser(String userId, String userName) {
        try{
                //添加打印日志的功能
                //开始添加用户
                System.out.println("start-->addUser()");
                userManager.addUser(userId, userName);
                //添加用户成功
                System.out.println("success-->addUser()");
            }catch(Exception e){
                //添加用户失败
                System.out.println("error-->addUser()");
            }
    }

}

为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别。通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间,从而在设计上获得了更大的灵活性。

更通俗的说,代理解决的问题当两个类需要通信时,引入第三方代理类,将两个类的关系解耦,让我们只了解代理类即可,而且代理的出现还可以让我们完成与另一个类之间的关系的统一管理,但是切记,代理类和委托类要实现相同的接口,因为代理真正调用的还是委托类的方法。

动态代理

按照代理的创建时期,代理类可以分为两种:

静态:由程序员创建代理类或特定工具自动生成源代码再对其编译。在程序运行前代理类的.class文件就已经存在了。而动态:在程序运行时运用反射机制动态创建而成。

Java 动态代理创建:

  • 定义实现接口InvocationHandler
  • 调用(T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { interfaces }, h)

源码分析

先介绍几个核心对象

  • MapperProxyFactory
  • MapperProxy

分析

MapperProxyFactory

//Mapper 的代理工厂,用于创建Mapper的代理对象
public class MapperProxyFactory<T> {

  private final Class<T> mapperInterface;
  private final Map<Method, MapperMethodInvoker> methodCache = new ConcurrentHashMap<>();

  public MapperProxyFactory(Class<T> mapperInterface) {
    this.mapperInterface = mapperInterface;
  }

  public Class<T> getMapperInterface() {
    return mapperInterface;
  }

  public Map<Method, MapperMethodInvoker> getMethodCache() {
    return methodCache;
  }

  //JDK的动态代理
  @SuppressWarnings("unchecked")
  protected T newInstance(MapperProxy<T> mapperProxy) {
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }

  //重载方法,生成实例
  public T newInstance(SqlSession sqlSession) {
    //代理增强(触发管理)处理类
    final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
    return newInstance(mapperProxy);
  }

}
//MapperProxy必须要实现InvocationHandler,用于代理方法执行时invoke进行增强调用
public class MapperProxy<T> implements InvocationHandler, Serializable {

  private static final long serialVersionUID = -4724728412955527868L;
  private static final int ALLOWED_MODES = Lookup.PRIVATE | Lookup.PROTECTED
      | Lookup.PACKAGE | Lookup.PUBLIC;
  private static final Constructor<Lookup> lookupConstructor;
  private static final Method privateLookupInMethod;
  private final SqlSession sqlSession;
  private final Class<T> mapperInterface;
  private final Map<Method, MapperMethodInvoker> methodCache;

  public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface, Map<Method, MapperMethodInvoker> methodCache) {
    this.sqlSession = sqlSession;
    this.mapperInterface = mapperInterface;
    this.methodCache = methodCache;
  }

  static {
    Method privateLookupIn;
    try {
      privateLookupIn = MethodHandles.class.getMethod("privateLookupIn", Class.class, Lookup.class);
    } catch (NoSuchMethodException e) {
      privateLookupIn = null;
    }
    privateLookupInMethod = privateLookupIn;

    Constructor<Lookup> lookup = null;
    if (privateLookupInMethod == null) {
      // JDK 1.8
      try {
        lookup = Lookup.class.getDeclaredConstructor(Class.class, int.class);
        lookup.setAccessible(true);
      } catch (NoSuchMethodException e) {
        throw new IllegalStateException(
            "There is neither 'privateLookupIn(Class, Lookup)' nor 'Lookup(Class, int)' method in java.lang.invoke.MethodHandles.",
            e);
      } catch (Exception e) {
        lookup = null;
      }
    }
    lookupConstructor = lookup;
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    try {
      //如果当前类直接时顶层父类,直接调用invoke方法
      if (Object.class.equals(method.getDeclaringClass())) {
        return method.invoke(this, args);
      } else {
        //如果不是,获取方法的缓存,进行解析
        return cachedInvoker(method).invoke(proxy, method, args, sqlSession);
      }
    } catch (Throwable t) {
      throw ExceptionUtil.unwrapThrowable(t);
    }
  }

  private MapperMethodInvoker cachedInvoker(Method method) throws Throwable {
    try {
      return methodCache.computeIfAbsent(method, m -> {
        if (m.isDefault()) {
          try {
            if (privateLookupInMethod == null) {
              return new DefaultMethodInvoker(getMethodHandleJava8(method));
            } else {
              return new DefaultMethodInvoker(getMethodHandleJava9(method));
            }
          } catch (IllegalAccessException | InstantiationException | InvocationTargetException
              | NoSuchMethodException e) {
            throw new RuntimeException(e);
          }
        } else {
          return new PlainMethodInvoker(new MapperMethod(mapperInterface, method, sqlSession.getConfiguration()));
        }
      });
    } catch (RuntimeException re) {
      Throwable cause = re.getCause();
      throw cause == null ? re : cause;
    }
  }

  private MethodHandle getMethodHandleJava9(Method method)
      throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
    final Class<?> declaringClass = method.getDeclaringClass();
    return ((Lookup) privateLookupInMethod.invoke(null, declaringClass, MethodHandles.lookup())).findSpecial(
        declaringClass, method.getName(), MethodType.methodType(method.getReturnType(), method.getParameterTypes()),
        declaringClass);
  }

  private MethodHandle getMethodHandleJava8(Method method)
      throws IllegalAccessException, InstantiationException, InvocationTargetException {
    final Class<?> declaringClass = method.getDeclaringClass();
    return lookupConstructor.newInstance(declaringClass, ALLOWED_MODES).unreflectSpecial(method, declaringClass);
  }

  interface MapperMethodInvoker {
    Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable;
  }

  private static class PlainMethodInvoker implements MapperMethodInvoker {
    private final MapperMethod mapperMethod;

    public PlainMethodInvoker(MapperMethod mapperMethod) {
      super();
      this.mapperMethod = mapperMethod;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable {
      return mapperMethod.execute(sqlSession, args);
    }
  }

  private static class DefaultMethodInvoker implements MapperMethodInvoker {
    private final MethodHandle methodHandle;

    public DefaultMethodInvoker(MethodHandle methodHandle) {
      super();
      this.methodHandle = methodHandle;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable {
      return methodHandle.bindTo(proxy).invokeWithArguments(args);
    }
  }
}

MapperRegistry

Mapper 的注册中心,所有解析的Mapper信息都存储在缓存中。

public class MapperRegistry {

  private final Configuration config;
  private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<>();

  public MapperRegistry(Configuration config) {
    this.config = config;
  }

  @SuppressWarnings("unchecked")
  public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
    final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
    if (mapperProxyFactory == null) {
      throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
    }
    try {
      return mapperProxyFactory.newInstance(sqlSession);
    } catch (Exception e) {
      throw new BindingException("Error getting mapper instance. Cause: " + e, e);
    }
  }

  public <T> boolean hasMapper(Class<T> type) {
    return knownMappers.containsKey(type);
  }

  //添加Mapper映射处理器到缓存
  public <T> void addMapper(Class<T> type) {
    if (type.isInterface()) {
      if (hasMapper(type)) {
        throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
      }
      boolean loadCompleted = false;
      try {
        knownMappers.put(type, new MapperProxyFactory<>(type));
        // It's important that the type is added before the parser is run
        // otherwise the binding may automatically be attempted by the
        // mapper parser. If the type is already known, it won't try.
        MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
        parser.parse();
        loadCompleted = true;
      } finally {
        if (!loadCompleted) {
          knownMappers.remove(type);
        }
      }
    }
  }

  /**
   * @since 3.2.2
   */
  public Collection<Class<?>> getMappers() {
    return Collections.unmodifiableCollection(knownMappers.keySet());
  }

  /**
   * @since 3.2.2
   */
  public void addMappers(String packageName, Class<?> superType) {
    ResolverUtil<Class<?>> resolverUtil = new ResolverUtil<>();
    resolverUtil.find(new ResolverUtil.IsA(superType), packageName);
    Set<Class<? extends Class<?>>> mapperSet = resolverUtil.getClasses();
    for (Class<?> mapperClass : mapperSet) {
      addMapper(mapperClass);
    }
  }

  /**
   * @since 3.2.2
   */
  public void addMappers(String packageName) {
    addMappers(packageName, Object.class);
  }

}

.

查询流程图:Mapper映射处理器生成流程

sequenceDiagram
Title:Mapper映射处理器生成流程(class形式)
XMLConfigBuilder-->>XMLConfigBuilder:解析配置:parse
XMLConfigBuilder-->>XMLConfigBuilder:解析Mapper节点:mapperElement
XMLConfigBuilder-->>XMLConfigBuilder:判断加载类型,package、url、resource、class
XMLConfigBuilder-->>Configuration:添加Mapper:addMapper
Configuration-->>MapperRegistry:委托处理:addMapper
MapperRegistry-->>MapperProxyFactory:包裹new(type)
MapperRegistry-->>MapperRegistry: knownMappers.put(type, new MapperProxyFactory<>(type));

深入动态代理源码

.

核心组件 Proxy

@SuppressWarnings("unchecked")
  protected T newInstance(MapperProxy<T> mapperProxy) {
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }
  • 核心方法:newProxyInstance
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)
    throws IllegalArgumentException
{
    Objects.requireNonNull(h);
        //安全校验
    final Class<?>[] intfs = interfaces.clone();
    final SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
    }

    /*
     * Look up or generate the designated proxy class.
     */
      //内存中生成Class定义
    Class<?> cl = getProxyClass0(loader, intfs);

    /*
     * Invoke its constructor with the designated invocation handler.
     */
    try {
        if (sm != null) {
            checkNewProxyPermission(Reflection.getCallerClass(), cl);
        }
                //获取Class的构造函数
        final Constructor<?> cons = cl.getConstructor(constructorParams);
        final InvocationHandler ih = h;
        if (!Modifier.isPublic(cl.getModifiers())) {
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
                public Void run() {
                    cons.setAccessible(true);
                    return null;
                }
            });
        }
          //实例化对象
        return cons.newInstance(new Object[]{h});
    } catch (IllegalAccessException|InstantiationException e) {
        throw new InternalError(e.toString(), e);
    } catch (InvocationTargetException e) {
        Throwable t = e.getCause();
        if (t instanceof RuntimeException) {
            throw (RuntimeException) t;
        } else {
            throw new InternalError(t.toString(), t);
        }
    } catch (NoSuchMethodException e) {
        throw new InternalError(e.toString(), e);
    }
}
//getProxyClass0
/**
     * Generate a proxy class.  Must call the checkProxyAccess method
     * to perform permission checks before calling this.
     */
    private static Class<?> getProxyClass0(ClassLoader loader,
                                           Class<?>... interfaces) {
      //类的接口数目限制  
      if (interfaces.length > 65535) {
            throw new IllegalArgumentException("interface limit exceeded");
        }

        // If the proxy class defined by the given loader implementing
        // the given interfaces exists, this will simply return the cached copy;
        // otherwise, it will create the proxy class via the ProxyClassFactory
          //优先从缓存拿代理对象的Class,没有的话通过ProxyClassFactory来创建
        return proxyClassCache.get(loader, interfaces);
    }
//proxyClassCache.get(loader, interfaces);
public V get(K key, P parameter) {
              //1. 从缓存读取代理对象的Class
        Objects.requireNonNull(parameter);

        expungeStaleEntries();

        Object cacheKey = CacheKey.valueOf(key, refQueue);

        // lazily install the 2nd level valuesMap for the particular cacheKey
        ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
        if (valuesMap == null) {
            ConcurrentMap<Object, Supplier<V>> oldValuesMap
                = map.putIfAbsent(cacheKey,
                                  valuesMap = new ConcurrentHashMap<>());
            if (oldValuesMap != null) {
                valuesMap = oldValuesMap;
            }
        }

        // create subKey and retrieve the possible Supplier<V> stored by that
        // subKey from valuesMap
              //缓存没有的话就创建
        Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
        Supplier<V> supplier = valuesMap.get(subKey);
        Factory factory = null;

        while (true) {
            if (supplier != null) {
                // supplier might be a Factory or a CacheValue<V> instance
                V value = supplier.get();
                if (value != null) {
                    return value;
                }
            }
            // else no supplier in cache
            // or a supplier that returned null (could be a cleared CacheValue
            // or a Factory that wasn't successful in installing the CacheValue)

            // lazily construct a Factory
            if (factory == null) {
                factory = new Factory(key, parameter, subKey, valuesMap);
            }

            if (supplier == null) {
                supplier = valuesMap.putIfAbsent(subKey, factory);
                if (supplier == null) {
                    // successfully installed Factory
                    supplier = factory;
                }
                // else retry with winning supplier
            } else {
                if (valuesMap.replace(subKey, supplier, factory)) {
                    // successfully replaced
                    // cleared CacheEntry / unsuccessful Factory
                    // with our Factory
                    supplier = factory;
                } else {
                    // retry with current supplier
                    supplier = valuesMap.get(subKey);
                }
            }
        }
    }
  • 生成代理对象Class

.

//subKeyFactory.apply(key, parameter)
 private static final class ProxyClassFactory
        implements BiFunction<ClassLoader, Class<?>[], Class<?>>
    {
        // prefix for all proxy class names
               //代理类名前缀
        private static final String proxyClassNamePrefix = "$Proxy";

        // next number to use for generation of unique proxy class names
        private static final AtomicLong nextUniqueNumber = new AtomicLong();
@Override
        public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {

            Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
              //校验接口
            for (Class<?> intf : interfaces) {
                /*
                 * Verify that the class loader resolves the name of this
                 * interface to the same Class object.
                 */
                Class<?> interfaceClass = null;
                try {
                    interfaceClass = Class.forName(intf.getName(), false, loader);
                } catch (ClassNotFoundException e) {
                }
                if (interfaceClass != intf) {
                    throw new IllegalArgumentException(
                        intf + " is not visible from class loader");
                }
                /*
                 * Verify that the Class object actually represents an
                 * interface.
                 */
                if (!interfaceClass.isInterface()) {
                    throw new IllegalArgumentException(
                        interfaceClass.getName() + " is not an interface");
                }
                /*
                 * Verify that this interface is not a duplicate.
                 */
                if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
                    throw new IllegalArgumentException(
                        "repeated interface: " + interfaceClass.getName());
                }
            }

            String proxyPkg = null;     // package to define proxy class in
            int accessFlags = Modifier.PUBLIC | Modifier.FINAL;

            /*
             * Record the package of a non-public proxy interface so that the
             * proxy class will be defined in the same package.  Verify that
             * all non-public proxy interfaces are in the same package.
             */
            for (Class<?> intf : interfaces) {
                int flags = intf.getModifiers();
                if (!Modifier.isPublic(flags)) {
                    accessFlags = Modifier.FINAL;
                    String name = intf.getName();
                    int n = name.lastIndexOf('.');
                    String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
                    if (proxyPkg == null) {
                        proxyPkg = pkg;
                    } else if (!pkg.equals(proxyPkg)) {
                        throw new IllegalArgumentException(
                            "non-public interfaces from different packages");
                    }
                }
            }

            if (proxyPkg == null) {
                // if no non-public proxy interfaces, use com.sun.proxy package
                proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
            }

            /*
             * Choose a name for the proxy class to generate.
             */
            long num = nextUniqueNumber.getAndIncrement();
              //拼接代理类名
            String proxyName = proxyPkg + proxyClassNamePrefix + num;

            /*
             * Generate the specified proxy class.
             */
              //生成Java字节码文件
            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                proxyName, interfaces, accessFlags);
            try {
                  //创建Class对象
                return defineClass0(loader, proxyName,
                                    proxyClassFile, 0, proxyClassFile.length);
            } catch (ClassFormatError e) {
                /*
                 * A ClassFormatError here means that (barring bugs in the
                 * proxy class generation code) there was some other
                 * invalid aspect of the arguments supplied to the proxy
                 * class creation (such as virtual machine limitations
                 * exceeded).
                 */
                throw new IllegalArgumentException(e.toString());
            }
        }
 }
//generateProxyClass

//defineClass0:本地方法
 private static native Class<?> defineClass0(ClassLoader loader, String name,
                                                byte[] b, int off, int len);

测试Class对象的输出

  • 定义代理对象和InvocationHandler
@AllArgsConstructor
@NoArgsConstructor
public class ProductHandler implements InvocationHandler {

    /**
     * 被代理对象
     */
    private ProductProcessor target;

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("print Product Info!" + args[0].toString());
        System.out.println(">>>"+proxy.getClass().getSimpleName());
        return method.invoke(target, args);
    }
}

@Data
@ToString
public class Product {

    private String name;
}

public interface ProductProcessor {

    /**
     * 加工
     *
     * @param product
     */
    void processor(Product product);

}

public class ProxyTest {

    private static final String proxyClassNamePrefix = "$Proxy";

    public static void main(String[] args) {
        ClassGeneratorUtil.generateProxyClass(proxyClassNamePrefix+"0",new Class[]{ProductHandler.class});
    }

}
  • 定义输出class文件的方法
/*
 * @ProjectName: 编程学习
 * @Copyright:   2019 HangZhou Helios Dev, Ltd. All Right Reserved.
 * @address:     微信搜索公众号「架构探险之道」获取更多资源。
 * @date:        2020/5/24 11:58 下午
 * @description: 本内容仅限于编程技术学习使用,转发请注明出处.
 */
package com.yido.example.invoke;

import sun.misc.ProxyGenerator;

import java.io.FileOutputStream;

/**
 * <p>
 *
 * </p>
 *
 * @author Helios
 * @date 2020/5/24 11:58 下午
 */
public class ClassGeneratorUtil {

    /**
     * 生成Class文件
     * @param proxyName
     * @param interfaces
     */
    public static void generateProxyClass(String proxyName, Class<?>[] interfaces) {
        byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
                proxyName, interfaces);
        String path = ClassGeneratorUtil.class.getResource(".").getPath();
        try (FileOutputStream fo = new FileOutputStream(path + proxyName + ".class")) {
            fo.write(proxyClassFile);
            fo.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 输出结果分析
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

import com.yido.example.invoke.ProductHandler;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class $Proxy0 extends Proxy implements ProductHandler {
    private static Method m1;
    private static Method m8;
    private static Method m2;
    private static Method m3;
    private static Method m5;
    private static Method m4;
    private static Method m7;
    private static Method m9;
    private static Method m0;
    private static Method m6;

    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 notify() throws  {
        try {
            super.h.invoke(this, m8, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    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 Object invoke(Object var1, Method var2, Object[] var3) throws Throwable {
        //代理类的invoke方法被调用,使用父类的 InvocationHandler 变量,来完成代理方法的调用
        return (Object)super.h.invoke(this, m3, new Object[]{var1, var2, var3});
    }

    public final void wait(long var1) throws InterruptedException {
        try {
            super.h.invoke(this, m5, new Object[]{var1});
        } catch (RuntimeException | InterruptedException | Error var4) {
            throw var4;
        } catch (Throwable var5) {
            throw new UndeclaredThrowableException(var5);
        }
    }

    public final void wait(long var1, int var3) throws InterruptedException {
        try {
            super.h.invoke(this, m4, new Object[]{var1, var3});
        } catch (RuntimeException | InterruptedException | Error var5) {
            throw var5;
        } catch (Throwable var6) {
            throw new UndeclaredThrowableException(var6);
        }
    }

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

    public final void notifyAll() throws  {
        try {
            super.h.invoke(this, m9, (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);
        }
    }

    public final void wait() throws InterruptedException {
        try {
            super.h.invoke(this, m6, (Object[])null);
        } catch (RuntimeException | InterruptedException | 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"));
            m8 = Class.forName("com.yido.example.invoke.ProductHandler").getMethod("notify");
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m3 = Class.forName("com.yido.example.invoke.ProductHandler").getMethod("invoke", Class.forName("java.lang.Object"), Class.forName("java.lang.reflect.Method"), Class.forName("[Ljava.lang.Object;"));
            m5 = Class.forName("com.yido.example.invoke.ProductHandler").getMethod("wait", Long.TYPE);
            m4 = Class.forName("com.yido.example.invoke.ProductHandler").getMethod("wait", Long.TYPE, Integer.TYPE);
            m7 = Class.forName("com.yido.example.invoke.ProductHandler").getMethod("getClass");
            m9 = Class.forName("com.yido.example.invoke.ProductHandler").getMethod("notifyAll");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
            m6 = Class.forName("com.yido.example.invoke.ProductHandler").getMethod("wait");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}
  • 代码执行测试
public class ProxyTest {

    private static final String proxyClassNamePrefix = "$Proxy";

    public static void main(String[] args) {
        //ClassGeneratorUtil.generateProxyClass(proxyClassNamePrefix+"0",new Class[]{ProductHandler.class});
        Product product = new Product();
        product.setName("苹果iPhone SE");
        //创建被代理对象
        DefaultProductProcessor defaultProductProcessor = new DefaultProductProcessor();
        //生成代理对象
        ProductProcessor processor = (ProductProcessor) Proxy.newProxyInstance(defaultProductProcessor.getClass().getClassLoader(),
                defaultProductProcessor.getClass().getInterfaces(), new ProductHandler(defaultProductProcessor));
        //执行代理对象的方法
        processor.process(product);
    }

}
//日志
print Product Info!Product(name=苹果iPhone SE)
>>>$Proxy0

调用链路

sequenceDiagram
Title:动态代理
ProductProcessor->>Proxy:生成代理类newProxyInstance
ProductProcessor->>ProductProcessor:process
ProductProcessor->>$Proxy0:m3: ProductHandler.invoke(Object,Method,Object2)
$Proxy0->>Proxy:super.h.invoke(this, m3, new Object[]{var1, var2, var3})
Proxy->>ProductHandler:method(process):invoke
ProductHandler->>ProductHandler:invoke,并进行代理修饰操作
ProductHandler ->> ProductHandler:proxy参数为代理类$Proxy0,对应上文传入的var1

.

在这里插入图片描述

小结

  • JDK动态代理的核心角色:被代理类(实现类)、接口、实现InvocationHandler的触发管理类。
  • 启动初期,便会解析配置,生成所有预处理数据,绑定每一个statement,在缓存中保存对应的接口信息。
  • 获取Mapper对象的过程,实质是获取一个动态代理对象。这个代理类会继承Proxy类,实现被代理的接口,里面持有了一个MapperProxy的触发管理类。
  • 动态代理本质上是利用自定义接口进行方法申明,利用InvocationHandler进行代理修饰的定义,通过invoke方法进行代理对象的调用,代理对象本生也会生成对应的Class文件,存储在内存或硬盘中。

.

本文分享自微信公众号 - 架构探险之道(zacsnz1314),作者:MasterYang

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-05-25

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • [Redis] 分布式缓存中间件 Redis 之 分布式锁实战

    环境准备Redis 如何实现分布式锁线程不安全单机锁分布式锁代码实现Redisson 集成和源码分析Redisson 集成源码分析 `RedissonLock`...

    架构探险之道
  • [Spring Boot] Spring Boot 装配实现原理

    本文就 Spring Boot 的配置装配实现方式做了介绍,主要是常用的模式注解、@EnableXXX注解、条件注解和自动装配是如何实现的。

    架构探险之道
  • [Spring Boot] Spring boot 整合mybatis、postgresql [Gradle构建项目]

    架构探险之道
  • 【小家Spring】Spring AOP原理使用的基础类打点(AopInfrastructureBean、ProxyProcessorSupport、Advised、AjType)

    Spring AOP是整个Spring框架中最重要的内容之一。为了更好的深入查看它的原理,这篇文章主要是把它在关键位置使用到的一些常用类进行打点、解释一波,有助...

    YourBatman
  • 简单的java实验,涉及到 类继承以及接口问题,方法体的重写(区别于重载)

    1 package test ; 2 abstract class Animal 3 { 4 abstract void cry(); ...

    Gxjun
  • Java 多线程

    黑白格
  • golang——为什么有的语言要把变量类型写在后面?

    Golang当中的变量类型和C/C++比较接近,一般用的比较多的也就是int,float和字符串。Golang当中不一样的地方主要有几点,第一点是严格区分了in...

    TechFlow-承志
  • 代理模式

    JDK动态代理的对象必须要实现接口,所以对于一些没有实现接口要被代理的对象,不适用JDK动态代理;cglib是通过继承被代理类,重写方法,织入通知通过动态字节码...

    OPice
  • java基础io流——字符流的变革(深入浅出)

    在io流里,先诞生了字节流,但是字节流读取数据会有乱码的问题(读中文会乱码)。比如:

    100000860378
  • 原生JS自己构建一个0-1之间的随机小数

    原生JS自己构建一个0-1之间的随机小数 前言 我们都知道使用Math.random()来得到一个随机数。但是很多人都没有深入的思考过,如何这个随机数是怎么来的...

    FungLeo

扫码关注云+社区

领取腾讯云代金券