当前位置: 首页 > news >正文

本地网站建设流程/深圳推广公司哪家好

本地网站建设流程,深圳推广公司哪家好,做网站的代码,台州新农村建设网站IObject proxy (IObject) Proxy.newProxyInstance(IObject.class.getClassLoader(),                              new Class[]{IObject.class},new DynamicProxyHandler(real) ); 使用Proxy类的静态方法new…
IObject proxy = (IObject) Proxy.newProxyInstance(IObject.class.getClassLoader(),                                   
                             new Class[]{IObject.class},new DynamicProxyHandler(real) );

使用Proxy类的静态方法newProxyInstance创建一个动态代理类

查看API文档:

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)throws IllegalArgumentException
loader - 定义代理类的类加载器 
interfaces - 代理类要实现的接口列表 
h - 指派方法调用的调用处理程序 

1、JDK动态代理要求,被代理的必须是个接口,单纯的类则不行,即interfaces必须是接口

2、JDK代理所生成的代理类都会继承Proxy类,同时代理类会实现所有传入的接口列表(即interfaces),因此可以强制类型转换成接口类型。

3、如果非要代理一个没有实现接口的类,同时该类的方法与其他接口的方法相同,则需要利用反射实现

//利用反射获取你想代理的类的方法
Method myMethod = targetClass.getClass().getDeclaredMethod(method.getName(), method.getParameterTypes());myMethod.setAccessible(true);

4、newProxyInstance方法相当于getProxyClass方法

Proxy.getProxyClass(loader, interfaces).getConstructor(new Class[] { InvocationHandler.class }).newInstance(new Object[] { handler });

源码分析:

@CallerSensitivepublic static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)throws IllegalArgumentException{if (h == null) {throw new NullPointerException();}//拷贝一份所有接口的数组final Class<?>[] intfs = interfaces.clone();/*** 安全管理器主要用来防止恶意攻击,根据java安全策略文件觉得将哪组权限授予类* 每个java应用都有自己的安全管理器,* 如果要使用,可以在jvm启动时设定-Djava.security.manager选项,还可以同时指定安全策略文件。* 如果在应用中启用了Java安全管理器,却没有指定安全策略文件,那么Java安全管理器将使用默认的安全策略,它们是由位于目录$JAVA_HOME/jre /lib/security中的java.policy定义的。 */final SecurityManager sm = System.getSecurityManager();if (sm != null) {checkProxyAccess(Reflection.getCallerClass(), loader, intfs);}/*** 调用getProxyClass0方法拿到代理类的Class对象*/Class<?> cl = getProxyClass0(loader, intfs);

调用getProxyClass0:

 /** 代理类的缓存 */
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
        proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

private
static Class<?> getProxyClass0(ClassLoader loader,Class<?>... interfaces) {//如果目标类的接口数大于65535if (interfaces.length > 65535) {throw new IllegalArgumentException("interface limit exceeded");}// 如果代理类已经在缓存中,则直接取出,否则用ProxyClassFactory创建新代理类return proxyClassCache.get(loader, interfaces);}

调用WeakCache的get方法:

private final ReferenceQueue<K> refQueue
        = new ReferenceQueue<>();
/**
* K 表示key* P 表示parameters* V 表示value*/public V get(K key, P parameter) {//NullObject判断方法 Objects.requireNonNull(parameter);//清理持有弱引用的WeakHashMap这种数据结构 expungeStaleEntries();//从队列中获取cacheKeyObject cacheKey = CacheKey.valueOf(key, refQueue);

调用CacheKey的valueOf

java.lang.ref.Reference
Reference(T referent, ReferenceQueue<? super T> queue) {
        this.referent = referent;
        this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
    }

private
static final class CacheKey<K> extends WeakReference<K> {// a replacement for null keysprivate static final Object NULL_KEY = new Object();static <K> Object valueOf(K key, ReferenceQueue<K> refQueue) {return key == null ? NULL_KEY : new CacheKey<>(key, refQueue);}private final int hash;private CacheKey(K key, ReferenceQueue<K> refQueue) {super(key, refQueue);
       //返回给定对象的哈希码,
            //该代码与默认的方法 hashCode() 返回的代码一样,无论给定对象的类是否重写 hashCode()。null 引用的哈希码为 0。
this.hash = System.identityHashCode(key); }

ReferenceQueue的源码先暂时不分析,回到WeakCache中get方法

//利用懒加载的方式获取cacheKey对应的SupplierConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);//如果map中不存在cache键值对,则把cacheKey对应的键值对放进mapif (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// subKeyFactory.apply调用Proxy中KeyFactory静态类的apply方法Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
subKeyFactory.apply调用Proxy中KeyFactory静态类的apply方法
 private static final class KeyFactoryimplements BiFunction<ClassLoader, Class<?>[], Object>{@Overridepublic Object apply(ClassLoader classLoader, Class<?>[] interfaces) {switch (interfaces.length) {case 1: return new Key1(interfaces[0]); // the most frequentcase 2: return new Key2(interfaces[0], interfaces[1]);case 0: return key0;default: return new KeyX(interfaces);}}}

Key1、Key2、KeyX都是Proxy的内部类

/** Key1 and Key2 都是用来给实现了1个或者2个接口的代理类使用*/private static final class Key1 extends WeakReference<Class<?>> {private final int hash;Key1(Class<?> intf) {super(intf);this.hash = intf.hashCode();}@Overridepublic int hashCode() {return hash;}@Overridepublic boolean equals(Object obj) {Class<?> intf;return this == obj ||obj != null &&obj.getClass() == Key1.class &&(intf = get()) != null &&intf == ((Key1) obj).get();}}private static final class Key2 extends WeakReference<Class<?>> {private final int hash;private final WeakReference<Class<?>> ref2;Key2(Class<?> intf1, Class<?> intf2) {super(intf1);hash = 31 * intf1.hashCode() + intf2.hashCode();ref2 = new WeakReference<Class<?>>(intf2);}@Overridepublic int hashCode() {return hash;}@Overridepublic boolean equals(Object obj) {Class<?> intf1, intf2;return this == obj ||obj != null &&obj.getClass() == Key2.class &&(intf1 = get()) != null &&intf1 == ((Key2) obj).get() &&(intf2 = ref2.get()) != null &&intf2 == ((Key2) obj).ref2.get();}}/** 用来给实现了3个或3个以上接口的代理类使用*/private static final class KeyX {private final int hash;private final WeakReference<Class<?>>[] refs;KeyX(Class<?>[] interfaces) {hash = Arrays.hashCode(interfaces);refs = new WeakReference[interfaces.length];for (int i = 0; i < interfaces.length; i++) {refs[i] = new WeakReference(interfaces[i]);}}@Overridepublic int hashCode() {return hash;}@Overridepublic boolean equals(Object obj) {return this == obj ||obj != null &&obj.getClass() == KeyX.class &&equals(refs, ((KeyX) obj).refs);}private static boolean equals(WeakReference<Class<?>>[] refs1,WeakReference<Class<?>>[] refs2) {if (refs1.length != refs2.length) {return false;}for (int i = 0; i < refs1.length; i++) {Class<?> intf = refs1[i].get();if (intf == null || intf != refs2[i].get()) {return false;}}return true;}}

回到get方法:

//
        Supplier<V> supplier = valuesMap.get(subKey);Factory factory = null;while (true) {if (supplier != null) {//调用Factory实现的get方法,返回实现InvokeHandler的类,并包含了所需要的信息V value = supplier.get();if (value != null) {return value;}}//懒加载构建工厂if (factory == null) {/***创建一个工厂key           classloaderparameter  interfaces接口subkey     存储interfaces的对象valuesMap     cacheKey键值对*/factory = new Factory(key, parameter, subKey, valuesMap);}if (supplier == null) {supplier = valuesMap.putIfAbsent(subKey, factory);if (supplier == null) {//填充suppliersupplier = factory;}} else {if (valuesMap.replace(subKey, supplier, factory)) {supplier = factory;} else {supplier = valuesMap.get(subKey);}}}

调用Supplier子类Factory的get方法:

@Overridepublic synchronized V get() { // 重新检查supplierSupplier<V> supplier = valuesMap.get(subKey);if (supplier != this) {return null;}V value = null;try {//调用Proxy类种ProxyFactoryClass的apply方法,apply才是真正创建代理类的方法value = Objects.requireNonNull(valueFactory.apply(key, parameter));} finally {if (value == null) { // remove us on failurevaluesMap.remove(subKey, this);}}// the only path to reach here is with non-null valueassert value != null;// wrap value with CacheValue (WeakReference)CacheValue<V> cacheValue = new CacheValue<>(value);// try replacing us with CacheValue (this should always succeed)if (valuesMap.replace(subKey, this, cacheValue)) {// put also in reverseMap
                reverseMap.put(cacheValue, Boolean.TRUE);} else {throw new AssertionError("Should not reach here");}// successfully replaced us with new CacheValue -> return the value// wrapped by itreturn value;}

调用ProxyFactoryClass的apply方法:

private static final class ProxyClassFactoryimplements BiFunction<ClassLoader, Class<?>[], Class<?>>{//动态代理类的前缀private static final String proxyClassNamePrefix = "$Proxy";//最终动态代理类的名字一般都是$ProxyN (N=0,1,2,3,4,5,6,7,8)private static final AtomicLong nextUniqueNumber = new AtomicLong();//真正创建代理类的方法
        @Overridepublic 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) {}//如果使你自己定义的ClassLoader加载的class与你传入的class不一样,则抛出异常if (interfaceClass != intf) {throw new IllegalArgumentException(intf + " is not visible from class loader");}/** 判断Class对象是否是一个接口*/if (!interfaceClass.isInterface()) {throw new IllegalArgumentException(interfaceClass.getName() + " is not an interface");}/** 验证接口是否重复*/if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {throw new IllegalArgumentException("repeated interface: " + interfaceClass.getName());}}String proxyPkg = null;     // package to define proxy class in/** 检查传入的接口里有没有不是public的接口,如果有,这些接口必须在一个包里*/for (Class<?> intf : interfaces) {int flags = intf.getModifiers();if (!Modifier.isPublic(flags)) {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) {//如果没有非公共的代理接口, 则使用com.sun.proxy packageproxyPkg = ReflectUtil.PROXY_PACKAGE + ".";}//为生成的代理类选择一个名字 com.sun.proxy $Proxy0long num = nextUniqueNumber.getAndIncrement();String proxyName = proxyPkg + proxyClassNamePrefix + num;//生成代理类字节码byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces);try {//根据代理类的字节码生成代理类的实例return defineClass0(loader, proxyName,proxyClassFile, 0, proxyClassFile.length);} catch (ClassFormatError e) {throw new IllegalArgumentException(e.toString());}}}

调用ProxyGenerator.generateProxyClass( proxyName, interfaces);生成接口对应的字节码

public static byte[] generateProxyClass(final String name,Class[] interfaces){ProxyGenerator gen = new ProxyGenerator(name, interfaces);
//生成字节码
final byte[] classFile = gen.generateClassFile();if (saveGeneratedFiles) {java.security.AccessController.doPrivileged(new java.security.PrivilegedAction() {public Object run() {try {FileOutputStream file =new FileOutputStream(dotToSlash(name) + ".class");file.write(classFile);file.close();return null;} catch (IOException e) {throw new InternalError("I/O exception saving generated file: " + e);}}});}return classFile;}

调用Proxy.defineClass0本地方法把字节码生成代理类的实例

 

转载于:https://www.cnblogs.com/wangwanchao/p/6239113.html

http://www.jmfq.cn/news/5225545.html

相关文章:

  • 网站备案号中信息有变/上海有名网站建站开发公司
  • 做ppt常用的网站有哪些/唐山seo推广公司
  • 怎么评价网站做的好坏/中国去中心化搜索引擎
  • 生意街创业商机网/seo推广平台服务
  • 建网站电脑版和手机版怎么做/青岛官网seo公司
  • 湖南智能网站建设推荐/网络黄页推广软件哪个好用
  • 网站建设怎么选公司/今天重大新闻事件
  • 网站导航栏设计代码/百度搜索引擎优化怎么做
  • 完善运营网站建设/今日热搜榜排名最新
  • 云南省住房和城乡建设部网站/公司查询
  • web应用程序有哪些/seo人才
  • 南昌专业做网站的/社会化媒体营销
  • gta5地产网站建设中/今日热点新闻事件摘抄
  • 沈阳网站建设优化企业/竞价推广账户竞价托管费用
  • 天猫的网站导航怎么做的/搜索引擎营销的案例
  • 男人互做网站/电商网页
  • 贵州移动端网站建设/好的在线crm系统
  • 浙江二建建设集团有限公司网站/谷歌google 官网下载
  • jsp做门户网站/360开户
  • 南京h5网站建设/网络推广要求
  • 武汉营销型网站/商品关键词优化的方法
  • 微信公众号微网站开发/宁德市属于哪个省份
  • 怎么样才能创建自己的网站/域名批量查询工具
  • 做代购网站/免费网站建站平台
  • 新浪云部署wordpress/兰州seo培训
  • 目前网站开发应用到的技术有什么/网站排名
  • wordpress侧边栏缩略图/优势的seo网站优化排名
  • 开通微商城需要多少钱/南昌seo管理
  • 苏州交通网站建设/软文推广怎么做
  • 电子商务网站设计的认识/网络推广运营途径