电子商务网站设计小结,淘宝放单网站开发,wordpress密码访问,花店网站建设环境分析理解动态代理底层
public static Object newProxyInstance(ClassLoader loader,Class?[] interfaces,InvocationHandler h)根据我的理解#xff1a;
步骤 Objects.requireNonNull(h); 判断代理实例的调用处理程序对象不为空 也就是你目前实现的这个接口不为空 fin…理解动态代理底层
public static Object newProxyInstance(ClassLoader loader,Class?[] interfaces,InvocationHandler h)根据我的理解
步骤 Objects.requireNonNull(h); 判断代理实例的调用处理程序对象不为空 也就是你目前实现的这个接口不为空 final Class?[] intfs interfaces.clone();
final SecurityManager sm System.getSecurityManager();final Class?[] intfs interfaces.clone();这个是获得你这个接口的克隆对象final SecurityManager sm System.getSecInvocationHandlerurityManager();这个是获得安全管理器这里面是分配安全权限的地方。 这个安全管理器的应用场景是当运行未知的Java程序的时候该程序可能有恶意代码删除系统文件、重启系统等为了防止运行恶意代码对系统产生影响需要对运行的代码的权限进行控制这时候就要启用Java安全管理器。权限分为以下类别文件、套接字、网络、安全性、运行时、属性、AWT、反射和可序列化。 if (sm ! null) {checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}这里是判断安全管理器不为空然后执行代理访问的方法第一个是获得调用反射这个类的对象第二个参数就是你自己写的实现了InvocationHandler的类的对象第三个参数就是你代理的接口对象 这个方法的实现是 private static void checkProxyAccess(Class? caller,ClassLoader loader,Class?... interfaces){SecurityManager sm System.getSecurityManager();if (sm ! null) {ClassLoader ccl caller.getClassLoader();if (VM.isSystemDomainLoader(loader) !VM.isSystemDomainLoader(ccl)) {sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);}ReflectUtil.checkProxyPackageAccess(ccl, interfaces);}}SecurityManager sm System.getSecurityManager();这个同样是拿到系统安全管理器 if (sm ! null) {ClassLoader ccl caller.getClassLoader();if (VM.isSystemDomainLoader(loader) !VM.isSystemDomainLoader(ccl)) {sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);}ReflectUtil.checkProxyPackageAccess(ccl, interfaces);}这个先判断管理器是否为空不为空时1、获取Reflection调用反射这个类的对象的类加载器。2、判断调用我实现了InvocationHandler必须是系统类加载器的也就是AppClassLoader以及调用反射类的对象不能是系统类加载器(AppClassLoader)3、然后调用检查权限检查的是运行时权限4、·ReflectUtil.checkProxyPackageAccess(ccl, interfaces);检查代理包的访问public static final String PROXY_PACKAGE com.sun.proxy; Class? cl getProxyClass0(loader, intfs);这个获得代理类 private static Class? getProxyClass0(ClassLoader loader,Class?... interfaces) {if (interfaces.length 65535) {throw new IllegalArgumentException(interface limit exceeded);}// If the proxy class defined by the given loader implementing// the given interfaces exists, this will simply return the cached copy;// otherwise, it will create the proxy class via the ProxyClassFactoryreturn proxyClassCache.get(loader, interfaces);}上面是判断class字节码文件的大小的如果超出了就报错return中的get方方法就是搞缓存的 太多了不想看了 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 PrivilegedActionVoid() {public Void run() {cons.setAccessible(true);return null;}});}return cons.newInstance(new Object[]{h});1、获得安全管理器2、检查新代理的权限就是检查包名和类加载器3、判断代理类的修饰符是否为public不是的话就继续走4、就是设置权限可访问5、返回一个新实例