Java 随笔 代理模式 2-JDK

  • Post author:
  • Post category:java




0. 疫情让我想要保存几家村里面的外卖电话


MethodAccessor&Java反射机制



1. JDK代理类的创建过程



1.1 JdkDynamicAopProxy 创建

	public Object getProxy(@Nullable ClassLoader classLoader) {
		return
			// 其实,我们刚从这里出来,并返回了一个 AopProxy
			createAopProxy()
			// step into ...
			// 也就是说接下来我们分析的代理bean的创建只需跟踪JDK、cegLib的AopProxy的构造方法以及getProxy()即可
			.getProxy(classLoader);
	}


	public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
		Assert.notNull(config, "AdvisedSupport must not be null");
		if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {
			throw new AopConfigException("No advisors and no TargetSource specified");
		}
		// 整个构造过程非常无聊
		// 简单提一下这里入参的config其实就是我们new然后一顿set的ProxyFactory
		// ProxyFactory extends ProxyCreatorSupport
		this.advised = config;
	}
	
	@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);
		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
		// step into ...
		// 创建代理bean的实例
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}



1.2 生成代理类的Class(defindClass)

该过程也解释了:为何JDK动态代理,只能是代理接口的实现类

	// java.lang.reflect.Proxy#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);
        }

		// step into ...
		// 这里有说法的 <- 为什么可以获取代理类的Class实例 <- classloader.defindClass <- 生成代理类的字节码
		// 注意:这里把被代理类实现的所有接口传入
        /*
         * Look up or generate the designated proxy class.
         */
        Class<?> cl = getProxyClass0(loader, intfs);

        /*
         * Invoke its constructor with the designated invocation handler.
         */
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }

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

	// java.lang.reflect.Proxy#getProxyClass0
	private static Class<?> getProxyClass0(ClassLoader loader,
                                           Class<?>... interfaces) {
        if (interfaces.length > 65535) {
            throw new IllegalArgumentException("interface limit exceeded");
        }

		// step into ...
        // 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
        return proxyClassCache.get(loader, interfaces);
    }
	
	
	private final ReferenceQueue<K> refQueue
        = new ReferenceQueue<>();
	// the key type is Object for supporting null key
    private final ConcurrentMap<Object, ConcurrentMap<Object, Supplier<V>>> map
        = new ConcurrentHashMap<>();
	private final BiFunction<K, P, ?> subKeyFactory;
    private final BiFunction<K, P, V> valueFactory;
	// java.lang.reflect.WeakCache#get
	/**
     * Look-up the value through the cache. This always evaluates the
     * {@code subKeyFactory} function and optionally evaluates
     * {@code valueFactory} function if there is no entry in the cache for given
     * pair of (key, subKey) or the entry has already been cleared.
     *
     * @param key       possibly null key
     * @param parameter parameter used together with key to create sub-key and
     *                  value (should not be null)
     * @return the cached value (never null)
     * @throws NullPointerException if {@code parameter} passed in or
     *                              {@code sub-key} calculated by
     *                              {@code subKeyFactory} or {@code value}
     *                              calculated by {@code valueFactory} is null.
     */
    public V get(K key, P parameter) {
        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) {
				// step into ...
                // 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)) {
					// supplier其实就是一个factory
                    // successfully replaced
                    // cleared CacheEntry / unsuccessful Factory
                    // with our Factory
                    supplier = factory;
                } else {
                    // retry with current supplier
                    supplier = valuesMap.get(subKey);
                }
            }
        }
    }
	
	// java.lang.reflect.WeakCache.Factory#get
	@Override
	public synchronized V get() { // serialize access
		// re-check
		Supplier<V> supplier = valuesMap.get(subKey);
		if (supplier != this) {
			// something changed while we were waiting:
			// might be that we were replaced by a CacheValue
			// or were removed because of failure ->
			// return null to signal WeakCache.get() to retry
			// the loop
			return null;
		}
		// else still us (supplier == this)

		// create new value
		V value = null;
		try {
			// step into ...
			value = Objects.requireNonNull(valueFactory.apply(key, parameter));
		} finally {
			if (value == null) { // remove us on failure
				valuesMap.remove(subKey, this);
			}
		}
		// the only path to reach here is with non-null value
		assert value != null;

		// wrap value with CacheValue (WeakReference)
		CacheValue<V> cacheValue = new CacheValue<>(value);

		// put into reverseMap
		reverseMap.put(cacheValue, Boolean.TRUE);

		// try replacing us with CacheValue (this should always succeed)
		if (!valuesMap.replace(subKey, this, cacheValue)) {
			throw new AssertionError("Should not reach here");
		}

		// successfully replaced us with new CacheValue -> return the value
		// wrapped by it
		return value;
	}
	
	// java.lang.reflect.Proxy.ProxyClassFactory#apply
	@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 + ".";
		}

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

		// step into ...
		// 这里返回代理类的字节码
		/*
		 * Generate the specified proxy class.
		 */
		byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
			proxyName, interfaces, accessFlags);
		try {
			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());
		}
	}
	
	// sun.misc.ProxyGenerator#generateProxyClass(java.lang.String, java.lang.Class<?>[], int)
	public static byte[] generateProxyClass(final String var0, Class<?>[] var1, int var2) {
		// step into ...
		// 先得到代理类的构建器
        ProxyGenerator var3 = new ProxyGenerator(var0, var1, var2);
		// 开始一顿输出成字节数组
        final byte[] var4 = var3.generateClassFile();
        if (saveGeneratedFiles) {
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
                public Void run() {
                    try {
                        int var1 = var0.lastIndexOf(46);
                        Path var2;
                        if (var1 > 0) {
                            Path var3 = Paths.get(var0.substring(0, var1).replace('.', File.separatorChar));
                            Files.createDirectories(var3);
                            var2 = var3.resolve(var0.substring(var1 + 1, var0.length()) + ".class");
                        } else {
                            var2 = Paths.get(var0 + ".class");
                        }

                        Files.write(var2, var4, new OpenOption[0]);
                        return null;
                    } catch (IOException var4x) {
                        throw new InternalError("I/O exception saving generated file: " + var4x);
                    }
                }
            });
        }

        return var4;
    }
	
	// sun.misc.ProxyGenerator#generateClassFile
	private byte[] generateClassFile() {
		// 将三个默认代理的方法加上
        this.addProxyMethod(hashCodeMethod, Object.class);
        this.addProxyMethod(equalsMethod, Object.class);
        this.addProxyMethod(toStringMethod, Object.class);
		
		// 获取代理类实现的接口
        Class[] var1 = this.interfaces;
        int var2 = var1.length;

        int var3;
        Class var4;
        for(var3 = 0; var3 < var2; ++var3) {
            var4 = var1[var3];
			
			// 获取代理类实现接口的所有方法
            Method[] var5 = var4.getMethods();
            int var6 = var5.length;

            for(int var7 = 0; var7 < var6; ++var7) {
                Method var8 = var5[var7];
				
				// step into ...
				// 累加代理类实现接口的方法
                this.addProxyMethod(var8, var4);
            }
        }

        Iterator var11 = this.proxyMethods.values().iterator();

        List var12;
        while(var11.hasNext()) {
            var12 = (List)var11.next();
            checkReturnTypes(var12);
        }

        Iterator var15;
        try {
            this.methods.add(this.generateConstructor());
            var11 = this.proxyMethods.values().iterator();

            while(var11.hasNext()) {
                var12 = (List)var11.next();
                var15 = var12.iterator();

                while(var15.hasNext()) {
                    ProxyGenerator.ProxyMethod var16 = (ProxyGenerator.ProxyMethod)var15.next();
                    this.fields.add(new ProxyGenerator.FieldInfo(var16.methodFieldName, "Ljava/lang/reflect/Method;", 10));
                    this.methods.add(var16.generateMethod());
                }
            }

            this.methods.add(this.generateStaticInitializer());
        } catch (IOException var10) {
            throw new InternalError("unexpected I/O Exception", var10);
        }

        if (this.methods.size() > 65535) {
            throw new IllegalArgumentException("method limit exceeded");
        } else if (this.fields.size() > 65535) {
            throw new IllegalArgumentException("field limit exceeded");
        } else {
            this.cp.getClass(dotToSlash(this.className));
            this.cp.getClass("java/lang/reflect/Proxy");
            var1 = this.interfaces;
            var2 = var1.length;

            for(var3 = 0; var3 < var2; ++var3) {
                var4 = var1[var3];
                this.cp.getClass(dotToSlash(var4.getName()));
            }

            this.cp.setReadOnly();
            ByteArrayOutputStream var13 = new ByteArrayOutputStream();
            DataOutputStream var14 = new DataOutputStream(var13);

            try {
                var14.writeInt(-889275714);
                var14.writeShort(0);
                var14.writeShort(49);
                this.cp.write(var14);
                var14.writeShort(this.accessFlags);
                var14.writeShort(this.cp.getClass(dotToSlash(this.className)));
                var14.writeShort(this.cp.getClass("java/lang/reflect/Proxy"));
                var14.writeShort(this.interfaces.length);
                Class[] var17 = this.interfaces;
                int var18 = var17.length;

                for(int var19 = 0; var19 < var18; ++var19) {
                    Class var22 = var17[var19];
                    var14.writeShort(this.cp.getClass(dotToSlash(var22.getName())));
                }

                var14.writeShort(this.fields.size());
                var15 = this.fields.iterator();

				// 一顿循环将接口的代理类的接口方法写入代理类构建器
                while(var15.hasNext()) {
                    ProxyGenerator.FieldInfo var20 = (ProxyGenerator.FieldInfo)var15.next();
                    var20.write(var14);
                }

                var14.writeShort(this.methods.size());
                var15 = this.methods.iterator();
F
                while(var15.hasNext()) {
                    ProxyGenerator.MethodInfo var21 = (ProxyGenerator.MethodInfo)var15.next();
                    var21.write(var14);
                }

                var14.writeShort(0);
                return var13.toByteArray();
            } catch (IOException var9) {
                throw new InternalError("unexpected I/O Exception", var9);
            }
        }
    }



1.3 通过构造器反射创建代理类的实例

	// java.lang.reflect.Proxy#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<?> cl = getProxyClass0(loader, intfs);

        /*
         * Invoke its constructor with the designated invocation handler.
         */
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }

            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;
                    }
                });
            }
			// step into ...
            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);
        }
    }
	
	public T newInstance(Object ... initargs)
        throws InstantiationException, IllegalAccessException,
               IllegalArgumentException, InvocationTargetException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, null, modifiers);
            }
        }
        if ((clazz.getModifiers() & Modifier.ENUM) != 0)
            throw new IllegalArgumentException("Cannot reflectively create enum objects");
        ConstructorAccessor ca = constructorAccessor;   // read volatile
        if (ca == null) {
            ca = acquireConstructorAccessor();
        }
		// step into ...
        @SuppressWarnings("unchecked")
        T inst = (T) ca.newInstance(initargs);
        return inst;
    }
	
	public Object newInstance(Object[] var1) throws InstantiationException, IllegalArgumentException, InvocationTargetException {
		// step into ...
		// 委派给native本地实现方法
        return this.delegate.newInstance(var1);
    }
	
	public Object newInstance(Object[] var1) throws InstantiationException, IllegalArgumentException, InvocationTargetException {
        if (++this.numInvocations > ReflectionFactory.inflationThreshold() && !ReflectUtil.isVMAnonymousClass(this.c.getDeclaringClass())) {
            ConstructorAccessorImpl var2 = (ConstructorAccessorImpl)(new MethodAccessorGenerator()).generateConstructor(this.c.getDeclaringClass(), this.c.getParameterTypes(), this.c.getExceptionTypes(), this.c.getModifiers());
            this.parent.setDelegate(var2);
        }
		// step into ...
        return newInstance0(this.c, var1);
    }
	
	private static native Object newInstance0(Constructor<?> var0, Object[] var1) throws InstantiationException, IllegalArgumentException, InvocationTargetException;



2. 代理类实例在运行时的调用过程

	@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);
		findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
		// step into ...
		return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
	}
	
	@CallerSensitive
    public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
										  // step into ...
										  // 即传入的this已实现InvocationHandler接口
                                          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<?> cl = getProxyClass0(loader, intfs);

        /*
         * Invoke its constructor with the designated invocation handler.
         */
        try {
            if (sm != null) {
                checkNewProxyPermission(Reflection.getCallerClass(), cl);
            }

            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);
        }
    }
	
	// org.springframework.aop.framework.JdkDynamicAopProxy#invoke
	@Override
	@Nullable
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object oldProxy = null;
		boolean setProxyContext = false;

		TargetSource targetSource = this.advised.targetSource;
		Object target = null;

		try {
			if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
				// 代理equals()
				// The target does not implement the equals(Object) method itself.
				return equals(args[0]);
			}
			else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
				// 代理hashCode()
				// The target does not implement the hashCode() method itself.
				return hashCode();
			}
			else if (method.getDeclaringClass() == DecoratingProxy.class) {
				// There is only getDecoratedClass() declared -> dispatch to proxy config.
				return AopProxyUtils.ultimateTargetClass(this.advised);
			}
			else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
					method.getDeclaringClass().isAssignableFrom(Advised.class)) {
				// Service invocations on ProxyConfig with the proxy config...
				return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
			}

			Object retVal;

			// 如果设置了 exposeProxy,那么将 proxy 放到 ThreadLocal 中
			if (this.advised.exposeProxy) {
				// Make invocation available if necessary.
				oldProxy = AopContext.setCurrentProxy(proxy);
				setProxyContext = true;
			}

			// Get as late as possible to minimize the time we "own" the target,
			// in case it comes from a pool.
			target = targetSource.getTarget();
			Class<?> targetClass = (target != null ? target.getClass() : null);

			// 获取拦截器链(默认index:0为spring自带的ExposeInvocationInterceptor)
			// Get the interception chain for this method.
			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

			// 空链不需要执行增强
			// Check whether we have any advice. If we don't, we can fallback on direct
			// reflective invocation of the target, and avoid creating a MethodInvocation.
			if (chain.isEmpty()) {
				// We can skip creating a MethodInvocation: just invoke the target directly
				// Note that the final invoker must be an InvokerInterceptor so we know it does
				// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
				Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
			}
			else {
				// chain拦截器链、真实方法均传入这个构造(里面仅仅是赋值属性而已)
				// We need to create a method invocation...
				MethodInvocation invocation =
						new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				// 之后的递归调用参考 https://blog.csdn.net/weixin_43638238/article/details/126615336
				// 从这里开始执行代理增强的方法(如果有拦截器链的话)
				// 注释:在拦截器链中执行
				// Proceed to the joinpoint through the interceptor chain.
				retVal = invocation.proceed();
			}

			// Massage return value if necessary.
			Class<?> returnType = method.getReturnType();
			if (retVal != null && retVal == target &&
					returnType != Object.class && returnType.isInstance(proxy) &&
					!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
				// Special case: it returned "this" and the return type of the method
				// is type-compatible. Note that we can't help if the target sets
				// a reference to itself in another returned object.
				retVal = proxy;
			}
			else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
				throw new AopInvocationException(
						"Null return value from advice does not match primitive return type for: " + method);
			}
			return retVal;
		}
		finally {
			if (target != null && !targetSource.isStatic()) {
				// Must have come from TargetSource.
				targetSource.releaseTarget(target);
			}
			if (setProxyContext) {
				// Restore old proxy.
				AopContext.setCurrentProxy(oldProxy);
			}
		}
	}



3. jdk反射包下参与到代理的基类

此处的代理删减较多,详细代码可以参考上面的小节或者源码


  • java.lang.reflect:依赖并对sun.reflect的一些组件做了相应的封装:Method、Construct等(存在对应关系)
  • sun.reflect:包下的MethodAccessor、ConstructAccessor分别支撑了java反射方法调用、实例构造的能力
  • sun.misc:对sun.reflect包下MethodAccessor、ConstructAccessor等组建的构建过程的一个封装

这里不按代理类创建、调用的顺序,而是采用基类所在包的顺序描述(强调关联性)

@CallerSensitive注解:这个注解是Java修复用的。防止使用者使用双重反射来提升权限,原理是因为当时反射只检查深度的调用者的类是否有权限,本身的类是没有这么高权限的,但是可以通过多重反射来提高调用的权限。

使用该注解,getCallerClass方法就会直接跳过有 @CallerSensitive修饰的接口方法,直接查找真实的调用者(actual caller)。


这段引用的出处



3.1 java.lang.reflect



3.1.1 Proxy:jdk暴露的创建代理对象的类

public class Proxy implements java.io.Serializable {
	@CallerSensitive
	public static Object newProxyInstance(ClassLoader loader,
										  Class<?>[] interfaces,
										  InvocationHandler h)
		throws IllegalArgumentException
	{
		// 被代理类所实现的接口
		final Class<?>[] intfs = interfaces.clone();
		// 内部有一个cache
		// 如果没有命中,将调用内部私有的ProxyClassFactory生成代理类的字节码并且defindClass
		Class<?> cl = getProxyClass0(loader, intfs);
		final Constructor<?> cons = cl.getConstructor(constructorParams);
		final InvocationHandler ih = h;
		// 这里可以看到JDK代理可以借助反射代理private方法
		if (!Modifier.isPublic(cl.getModifiers())) {
			AccessController.doPrivileged(new PrivilegedAction<Void>() {
				public Void run() {
					cons.setAccessible(true);
					return null;
				}
			});
		}
		// 这个时候还是Constructor类型
		return cons.newInstance(new Object[]{h});
	}
	private static final class ProxyClassFactory implements BiFunction<ClassLoader, Class<?>[], Class<?>>
	{
		// jdk代理类前缀
		private static final String proxyClassNamePrefix = "$Proxy";
		// 新增&唯一的代理类数字编号
		private static final AtomicLong nextUniqueNumber = new AtomicLong();
		@Override
		public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
			// 代理类类名拼接规则
			long num = nextUniqueNumber.getAndIncrement();
			String proxyName = proxyPkg + proxyClassNamePrefix + num;
			// 代理类字节码
			byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
				proxyName, interfaces, accessFlags);
			// 加载到内存
			return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length);
		}
	}
	private static native Class<?> defineClass0(ClassLoader loader, String name, byte[] b, int off, int len);
}



3.1.2 InvocationHandler:jdk暴露的代理方法的调用时钩子

public interface InvocationHandler {
	public Object invoke(Object proxy, Method method, Object[] args)
		throws Throwable;
}

/* ------------ 这里插一段spring.aop借助这个接口参与到jdk代理类调用时的代码 ---------------*/

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
	@Override
	@Nullable
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object oldProxy = null;
		boolean setProxyContext = false;
		TargetSource targetSource = this.advised.targetSource;
		Object target = null;
		target = targetSource.getTarget();
		Class<?> targetClass = (target != null ? target.getClass() : null);
		// 获取用于增强被代理方法的所有advice
		List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
		// 将拦截器的增强过程在这里执行
		MethodInvocation invocation =
				new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
		// 这里使spring.aop的增强逻辑参与进来了
		retVal = invocation.proceed();
		Class<?> returnType = method.getReturnType();
		return retVal;
	}
}



3.1.3 Method & Construct

// Method -------------------------------
public final class Method extends Executable {
	private Method              root;	
	private volatile MethodAccessor methodAccessor;
	@CallerSensitive
	public Object invoke(Object obj, Object... args)
		throws IllegalAccessException, IllegalArgumentException,
		   InvocationTargetException
	{
		MethodAccessor ma = methodAccessor;             // read volatile
		return ma.invoke(obj, args);
	}
}

// Constructor -------------------------------
public final class Constructor<T> extends Executable {
	@CallerSensitive
	public T newInstance(Object ... initargs)
		throws InstantiationException, IllegalAccessException,
			   IllegalArgumentException, InvocationTargetException
	{
		ConstructorAccessor ca = constructorAccessor;   // read volatile
		T inst = (T) ca.newInstance(initargs);
		return inst;
	}
}



3.2 sun.reflect



3.2.1 ConstructAccessor及其子类

public interface ConstructorAccessor {
	Object newInstance(Object[] var1) throws InstantiationException, IllegalArgumentException, InvocationTargetException;
}

abstract class ConstructorAccessorImpl extends MagicAccessorImpl implements ConstructorAccessor {
	Object newInstance(Object[] var1) throws InstantiationException, IllegalArgumentException, InvocationTargetException;
}

class DelegatingConstructorAccessorImpl extends ConstructorAccessorImpl {
	// 持有 NativeConstructorAccessorImpl 的引用
	private ConstructorAccessorImpl delegate;
	public Object newInstance(Object[] var1) throws InstantiationException, IllegalArgumentException, InvocationTargetException {
		return this.delegate.newInstance(var1);
	}
}

class NativeConstructorAccessorImpl extends ConstructorAccessorImpl {
	// 也持有 DelegatingConstructorAccessorImpl 的引用
	private DelegatingConstructorAccessorImpl parent;
	public Object newInstance(Object[] var1) throws InstantiationException, IllegalArgumentException, InvocationTargetException {
		// Native版本一开始启动快,但是随着运行时间变长,速度变慢。Java版本一开始加载慢,但是随着运行时间变长,速度变快
		// 正是因为两种存在这些问题,所以第一次加载时使用的是NativeMethodAccessorImpl
		// 而当反射调用次数超过15次之后,则使用MethodAccessorGenerator生成的MethodAccessorImpl对象去实现反射。
		if (++this.numInvocations > ReflectionFactory.inflationThreshold() && !ReflectUtil.isVMAnonymousClass(this.c.getDeclaringClass())) {
			ConstructorAccessorImpl var2 = (ConstructorAccessorImpl)(new MethodAccessorGenerator()).generateConstructor(this.c.getDeclaringClass(), this.c.getParameterTypes(), this.c.getExceptionTypes(), this.c.getModifiers());
			this.parent.setDelegate(var2);
		}
		return newInstance0(this.c, var1);
	}
	// 底层使用本地支持来创建代理类
	private static native Object newInstance0(Constructor<?> var0, Object[] var1) throws InstantiationException, IllegalArgumentException, InvocationTargetException;
}



3.2.2 MethodAccessor及其子类

仔细看,跟ConstructAccessor差不多,这里就不解释了

public interface MethodAccessor {
	Object invoke(Object var1, Object[] var2) throws IllegalArgumentException, InvocationTargetException;
}

class DelegatingMethodAccessorImpl extends MethodAccessorImpl {
	private MethodAccessorImpl delegate;
	public Object invoke(Object var1, Object[] var2) throws IllegalArgumentException, InvocationTargetException {
		return this.delegate.invoke(var1, var2);
	}
}
		
class NativeMethodAccessorImpl extends MethodAccessorImpl {
	private final Method method;
	private DelegatingMethodAccessorImpl parent;
	public Object invoke(Object var1, Object[] var2) throws IllegalArgumentException, InvocationTargetException {
		if (++this.numInvocations > ReflectionFactory.inflationThreshold() && !ReflectUtil.isVMAnonymousClass(this.method.getDeclaringClass())) {
			MethodAccessorImpl var3 = (MethodAccessorImpl)(new MethodAccessorGenerator()).generateMethod(this.method.getDeclaringClass(), this.method.getName(), this.method.getParameterTypes(), this.method.getReturnType(), this.method.getExceptionTypes(), this.method.getModifiers());
			this.parent.setDelegate(var3);
		}
		return invoke0(this.method, var1, var2);
	}
	private static native Object invoke0(Method var0, Object var1, Object[] var2);
}



3.2.3 ReflectionFactory

public MethodAccessor newMethodAccessor(Method var1) {
	// 构造 NativeMethodAccessorImpl 、DelegatingMethodAccessorImpl 并使得持有对方的引用
	NativeMethodAccessorImpl var2 = new NativeMethodAccessorImpl(var1);
	DelegatingMethodAccessorImpl var3 = new DelegatingMethodAccessorImpl(var2);
	var2.setParent(var3);
	return var3;
}
public ConstructorAccessor newConstructorAccessor(Constructor<?> var1) {
	NativeConstructorAccessorImpl var3 = new NativeConstructorAccessorImpl(var1);
	DelegatingConstructorAccessorImpl var4 = new DelegatingConstructorAccessorImpl(var3);
	var3.setParent(var4);
	return var4;
}



3.3 sun.misc

写出生成好的代理类字节码文件

public class ProxyGenerator {
	public static byte[] generateProxyClass(final String var0, Class<?>[] var1, int var2) {
		ProxyGenerator var3 = new ProxyGenerator(var0, var1, var2);
		final byte[] var4 = var3.generateClassFile();
		if (saveGeneratedFiles) {
			AccessController.doPrivileged(new PrivilegedAction<Void>() {
				public Void run() {
					Files.write(var2, var4, new OpenOption[0]);
				}
			});
		}
		return var4;
	}
}



版权声明:本文为weixin_43638238原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。