掘金传送门

动态代理源码分析

Proxy.newProxyInstance实现

  1. public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,
  2. InvocationHandler h)
  3. throws IllegalArgumentException
  4. {
  5. //检验h不为空,h为空抛异常
  6. Objects.requireNonNull(h);
  7. //接口的类对象拷贝一份
  8. final Class<?>[] intfs = interfaces.clone();
  9. //进行一些安全性检查
  10. final SecurityManager sm = System.getSecurityManager();
  11. if (sm != null) {
  12. checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
  13. }
  14. /*
  15. * Look up or generate the designated proxy class.
  16. * 查询(在缓存中已经有)或生成指定的代理类的class对象。
  17. */
  18. Class<?> cl = getProxyClass0(loader, intfs);
  19. /*
  20. * Invoke its constructor with the designated invocation handler.
  21. */
  22. try {
  23. if (sm != null) {
  24. checkNewProxyPermission(Reflection.getCallerClass(), cl);
  25. }
  26. //得到代理类对象的构造函数,这个构造函数的参数由constructorParams指定
  27. //参数constructorParames为常量值:
  28. //private static final Class<?>[] constructorParams =
  29. //{ InvocationHandler.class };
  30. final Constructor<?> cons = cl.getConstructor(constructorParams);
  31. final InvocationHandler ih = h;
  32. if (!Modifier.isPublic(cl.getModifiers())) {
  33. AccessController.doPrivileged(new PrivilegedAction<Void>() {
  34. public Void run() {
  35. cons.setAccessible(true);
  36. return null;
  37. }
  38. });
  39. }
  40. //这里生成代理对象,传入的参数new Object[]{h}后面讲
  41. return cons.newInstance(new Object[]{h});
  42. } catch (IllegalAccessException|InstantiationException e) {
  43. throw new InternalError(e.toString(), e);
  44. } catch (InvocationTargetException e) {
  45. Throwable t = e.getCause();
  46. if (t instanceof RuntimeException) {
  47. throw (RuntimeException) t;
  48. } else {
  49. throw new InternalError(t.toString(), t);
  50. }
  51. } catch (NoSuchMethodException e) {
  52. throw new InternalError(e.toString(), e);
  53. }
  54. }

getProxyClass0实现

  1. //此方法也是Proxy类下的方法
  2. private static Class<?> getProxyClass0(ClassLoader loader,
  3. Class<?>... interfaces) {
  4. if (interfaces.length > 65535) {
  5. throw new IllegalArgumentException("interface limit exceeded");
  6. }
  7. // If the proxy class defined by the given loader implementing
  8. // the given interfaces exists, this will simply return the cached copy;
  9. // otherwise, it will create the proxy class via the ProxyClassFactory
  10. //意思是:如果代理类被指定的类加载器loader定义了,并实现了给定的接口interfaces,
  11. //那么就返回缓存的代理类对象,否则使用ProxyClassFactory创建代理类。
  12. return proxyClassCache.get(loader, interfaces);
  13. }

proxyClassCache 实现

  1. private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
  2. proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

WeakCache 类的成员变量和构造方法

  1. //K代表key的类型,P代表参数的类型,V代表value的类型。
  2. // WeakCache<ClassLoader, Class<?>[], Class<?>> proxyClassCache
  3. //说明proxyClassCache存的值是Class<?>对象,正是我们需要的代理类对象。
  4. final class WeakCache<K, P, V> {
  5. private final ReferenceQueue<K> refQueue
  6. = new ReferenceQueue<>();
  7. // the key type is Object for supporting null key
  8. private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map
  9. = new ConcurrentHashMap<>();
  10. private final ConcurrentMap<Supplier<V>, Boolean> reverseMap
  11. = new ConcurrentHashMap<>();
  12. private final BiFunction<K, P, ?> subKeyFactory;
  13. private final BiFunction<K, P, V> valueFactory;
  14. public WeakCache(BiFunction<K, P, ?> subKeyFactory,
  15. BiFunction<K, P, V> valueFactory) {
  16. this.subKeyFactory = Objects.requireNonNull(subKeyFactory);
  17. this.valueFactory = Objects.requireNonNull(valueFactory);
  18. }

proxyClassCache.get(loader, interfaces); 源码

  1. //K和P就是WeakCache定义中的泛型,key是类加载器,parameter是接口类数组
  2. public V get(K key, P parameter) {
  3. //检查parameter不为空
  4. Objects.requireNonNull(parameter);
  5. //清除无效的缓存
  6. expungeStaleEntries();
  7. // cacheKey就是(key, sub-key) -> value里的一级key,
  8. Object cacheKey = CacheKey.valueOf(key, refQueue);
  9. // lazily install the 2nd level valuesMap for the particular cacheKey
  10. //根据一级key得到 ConcurrentMap<Object, Supplier<V>>对象。如果之前不存在,
  11. //则新建一个ConcurrentMap<Object, Supplier<V>>和cacheKey(一级key)一起放到map中。
  12. /**
  13. * reference 懒加载
  14. */
  15. ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
  16. if (valuesMap == null) {
  17. ConcurrentMap<Object, Supplier<V>> oldValuesMap
  18. = map.putIfAbsent(cacheKey,
  19. valuesMap = new ConcurrentHashMap<>());
  20. if (oldValuesMap != null) {
  21. valuesMap = oldValuesMap;
  22. }
  23. }
  24. // create subKey and retrieve the possible Supplier<V> stored by that
  25. // subKey from valuesMap
  26. //这部分就是调用生成sub-key的代码,上面我们已经看过怎么生成的了
  27. Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
  28. //通过sub-key得到supplier
  29. Supplier<V> supplier = valuesMap.get(subKey);
  30. //supplier实际上就是这个factory
  31. Factory factory = null;
  32. while (true) {
  33. //如果缓存里有supplier ,那就直接通过get方法,得到代理类对象,返回,就结束了,
  34. //一会儿分析get方法。
  35. if (supplier != null) {
  36. // supplier might be a Factory or a CacheValue<V> instance
  37. V value = supplier.get();
  38. if (value != null) {
  39. return value;
  40. }
  41. }
  42. // else no supplier in cache
  43. // or a supplier that returned null (could be a cleared CacheValue
  44. // or a Factory that wasn't successful in installing the CacheValue)
  45. // lazily construct a Factory
  46. //下面的所有代码目的就是:如果缓存中没有supplier,
  47. //则创建一个Factory对象,把factory对象在多线程的环境下安全的赋给supplier。
  48. //因为是在while(true)中,赋值成功后又回到上面去调get方法,返回才结束。
  49. if (factory == null) {
  50. factory = new Factory(key, parameter, subKey, valuesMap);
  51. }
  52. if (supplier == null) {
  53. supplier = valuesMap.putIfAbsent(subKey, factory);
  54. if (supplier == null) {
  55. // successfully installed Factory
  56. supplier = factory;
  57. }
  58. // else retry with winning supplier
  59. } else {
  60. if (valuesMap.replace(subKey, supplier, factory)) {
  61. // successfully replaced
  62. // cleared CacheEntry / unsuccessful Factory
  63. // with our Factory
  64. supplier = factory;
  65. } else {
  66. // retry with current supplier
  67. supplier = valuesMap.get(subKey);
  68. }
  69. }
  70. }
  71. }

Factory类中的get方法

  1. public synchronized V get() { // serialize access
  2. // re-check
  3. Supplier<V> supplier = valuesMap.get(subKey);
  4. //重新检查得到的supplier是不是当前对象
  5. if (supplier != this) {
  6. // something changed while we were waiting:
  7. // might be that we were replaced by a CacheValue
  8. // or were removed because of failure ->
  9. // return null to signal WeakCache.get() to retry
  10. // the loop
  11. return null;
  12. }
  13. // else still us (supplier == this)
  14. // create new value
  15. V value = null;
  16. try {
  17. //代理类就是在这个位置调用valueFactory生成的
  18. //valueFactory就是我们传入的 new ProxyClassFactory()
  19. //一会我们分析ProxyClassFactory()的apply方法
  20. value = Objects.requireNonNull(valueFactory.apply(key, parameter));
  21. } finally {
  22. if (value == null) { // remove us on failure
  23. valuesMap.remove(subKey, this);
  24. }
  25. }
  26. // the only path to reach here is with non-null value
  27. assert value != null;
  28. // wrap value with CacheValue (WeakReference)
  29. //把value包装成弱引用
  30. CacheValue<V> cacheValue = new CacheValue<>(value);
  31. // put into reverseMap
  32. // reverseMap是用来实现缓存的有效性
  33. reverseMap.put(cacheValue, Boolean.TRUE);
  34. // try replacing us with CacheValue (this should always succeed)
  35. if (!valuesMap.replace(subKey, this, cacheValue)) {
  36. throw new AssertionError("Should not reach here");
  37. }
  38. // successfully replaced us with new CacheValue -> return the value
  39. // wrapped by it
  40. return value;
  41. }
  42. }

ProxyClassFactory

  1. //这里的BiFunction<T, U, R>是个函数式接口,可以理解为用T,U两种类型做参数,得到R类型的返回值
  2. private static final class ProxyClassFactory
  3. implements BiFunction<ClassLoader, Class<?>[], Class<?>>
  4. {
  5. // prefix for all proxy class names
  6. private static final String proxyClassNamePrefix = "$Proxy";
  7. // next number to use for generation of unique proxy class names
  8. private static final AtomicLong nextUniqueNumber = new AtomicLong();
  9. @Override
  10. public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
  11. Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
  12. for (Class<?> intf : interfaces) {
  13. /*
  14. * Verify that the class loader resolves the name of this
  15. * interface to the same Class object.
  16. */
  17. Class<?> interfaceClass = null;
  18. try {
  19. interfaceClass = Class.forName(intf.getName(), false, loader);
  20. } catch (ClassNotFoundException e) {
  21. }
  22. if (interfaceClass != intf) {
  23. throw new IllegalArgumentException(
  24. intf + " is not visible from class loader");
  25. }
  26. /*
  27. * Verify that the Class object actually represents an
  28. * interface.
  29. */
  30. if (!interfaceClass.isInterface()) {
  31. throw new IllegalArgumentException(
  32. interfaceClass.getName() + " is not an interface");
  33. }
  34. /*
  35. * Verify that this interface is not a duplicate.
  36. */
  37. if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
  38. throw new IllegalArgumentException(
  39. "repeated interface: " + interfaceClass.getName());
  40. }
  41. }
  42. String proxyPkg = null; // package to define proxy class in
  43. int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
  44. /*
  45. * Record the package of a non-public proxy interface so that the
  46. * proxy class will be defined in the same package. Verify that
  47. * all non-public proxy interfaces are in the same package.
  48. */
  49. for (Class<?> intf : interfaces) {
  50. int flags = intf.getModifiers();
  51. if (!Modifier.isPublic(flags)) {
  52. accessFlags = Modifier.FINAL;
  53. String name = intf.getName();
  54. int n = name.lastIndexOf('.');
  55. String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
  56. if (proxyPkg == null) {
  57. proxyPkg = pkg;
  58. } else if (!pkg.equals(proxyPkg)) {
  59. throw new IllegalArgumentException(
  60. "non-public interfaces from different packages");
  61. }
  62. }
  63. }
  64. if (proxyPkg == null) {
  65. // if no non-public proxy interfaces, use com.sun.proxy package
  66. proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
  67. }
  68. /*
  69. * Choose a name for the proxy class to generate.
  70. */
  71. long num = nextUniqueNumber.getAndIncrement();
  72. String proxyName = proxyPkg + proxyClassNamePrefix + num;
  73. /*
  74. * Generate the specified proxy class.
  75. */
  76. byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
  77. proxyName, interfaces, accessFlags);
  78. try {
  79. return defineClass0(loader, proxyName,
  80. proxyClassFile, 0, proxyClassFile.length);
  81. } catch (ClassFormatError e) {
  82. /*
  83. * A ClassFormatError here means that (barring bugs in the
  84. * proxy class generation code) there was some other
  85. * invalid aspect of the arguments supplied to the proxy
  86. * class creation (such as virtual machine limitations
  87. * exceeded).
  88. */
  89. throw new IllegalArgumentException(e.toString());
  90. }
  91. }
  92. }

得到动态代理字节码

  1. byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
  2. proxyName, interfaces, accessFlags);
  1. public class DynamicProxyTest {
  2. public static void main(String[] args) {
  3. //动态代理使用代码见掘金
  4. String path = "D:/$Proxy0.class";
  5. byte[] classFile = ProxyGenerator.generateProxyClass("$Proxy0", ServiceImpl.class.getInterfaces());
  6. FileOutputStream out = null;
  7. try {
  8. out = new FileOutputStream(path);
  9. out.write(classFile);
  10. out.flush();
  11. } catch (Exception e) {
  12. e.printStackTrace();
  13. } finally {
  14. try {
  15. out.close();
  16. } catch (IOException e) {
  17. e.printStackTrace();
  18. }
  19. }
  20. }
  21. }

JDK动态代理和CGLIB字节码生成的区别

  1. JDK动态代理只能对实现了接口的类生成代理,而不能针对类。
  2. CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,并覆盖其中方法实现增强,但是因为采用的是继承,所以该类或方法最好不要声明成final,对于final类或方法,是无法继承的。

CGLIB示例代码

  1. public class CGLibProxy implements MethodInterceptor {
  2. /** CGLib需要代理的目标对象 */
  3. private Object targetObject;
  4. public Object createProxyObject(Object obj) {
  5. this.targetObject = obj;
  6. Enhancer enhancer = new Enhancer();
  7. enhancer.setSuperclass(obj.getClass());
  8. enhancer.setCallback(this);
  9. Object proxyObj = enhancer.create();
  10. // 返回代理对象
  11. return proxyObj;
  12. }
  13. @Override
  14. public Object intercept(Object proxy, Method method, Object[] args,
  15. MethodProxy methodProxy) throws Throwable {
  16. Object obj = null;
  17. // 过滤方法
  18. if ("addUser".equals(method.getName())) {
  19. // 检查权限
  20. checkPopedom();
  21. }
  22. obj = method.invoke(targetObject, args);
  23. return obj;
  24. }
  25. private void checkPopedom() {
  26. System.out.println("======检查权限checkPopedom()======");
  27. }
  28. }

客户端测试类

  1. public class Client {
  2. public static void main(String[] args) {
  3. System.out.println("**********************CGLibProxy**********************");
  4. CGLibProxy cgLibProxy = new CGLibProxy();
  5. IUserManager userManager = (IUserManager) cgLibProxy.createProxyObject
  6. (new UserManagerImpl());
  7. //执行的是增强的add方法
  8. userManager.addUser("jpeony", "123456");
  9. }