• Java 随笔 代理模式 2-JDK


    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
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    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 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 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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411
    • 412
    • 413
    • 414
    • 415
    • 416
    • 417
    • 418
    • 419
    • 420
    • 421
    • 422
    • 423
    • 424
    • 425
    • 426
    • 427
    • 428
    • 429
    • 430
    • 431
    • 432
    • 433
    • 434
    • 435
    • 436
    • 437
    • 438
    • 439
    • 440
    • 441
    • 442
    • 443
    • 444
    • 445
    • 446
    • 447
    • 448

    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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92

    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);
    			}
    		}
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163

    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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    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;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    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;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    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;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    es 读流程源码解析
    04 MIT线性代数-矩阵的LU分解 Factorization into A=LU
    项目管理到底管的是什么?
    大数据学习笔记1:数据仓库的历史
    【优化后的Synchronized】Synchronized锁升级、⽆锁、偏向锁、轻量级锁、重量级锁、锁消除、锁粗化_JUC16
    2.RabbitMQ安装
    程序员必修课:阿里开源SpringBoot全栈小册
    400电话-400电话办理-400号码办理
    springboot整合jett导出数据(2)
    PHP设备检验系统Dreamweaver开发mysql数据库web结构php编程计算机网页代码
  • 原文地址:https://blog.csdn.net/weixin_43638238/article/details/126673112