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

品牌咖啡主题网页界面设计竞价推广和seo的区别

品牌咖啡主题网页界面设计,竞价推广和seo的区别,品牌设计,免费seo刷排名转载自 彻底理解JAVA动态代理 代理设计模式 定义#xff1a;为其他对象提供一种代理以控制对这个对象的访问。 代理模式的结构如下图所示。 动态代理使用 java动态代理机制以巧妙的方式实现了代理模式的设计理念。 代理模式示例代码 public interface Subject { pu…转载自 彻底理解JAVA动态代理 代理设计模式 定义为其他对象提供一种代理以控制对这个对象的访问。 代理模式的结构如下图所示。 动态代理使用 java动态代理机制以巧妙的方式实现了代理模式的设计理念。 代理模式示例代码 public interface Subject { public void doSomething(); } public class RealSubject implements Subject { public void doSomething() { System.out.println( call doSomething() ); } } public class ProxyHandler implements InvocationHandler { private Object proxied; public ProxyHandler( Object proxied ) { this.proxied proxied; } public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable { //在转调具体目标对象之前可以执行一些功能处理//转调具体目标对象的方法return method.invoke( proxied, args); //在转调具体目标对象之后可以执行一些功能处理} } import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import sun.misc.ProxyGenerator; import java.io.*; public class DynamicProxy { public static void main( String args[] ) { RealSubject real new RealSubject(); Subject proxySubject (Subject)Proxy.newProxyInstance(Subject.class.getClassLoader(), new Class[]{Subject.class}, new ProxyHandler(real));proxySubject.doSomething();//write proxySubject class binary data to file createProxyClassFile(); } public static void createProxyClassFile() { String name ProxySubject; byte[] data ProxyGenerator.generateProxyClass( name, new Class[] { Subject.class } ); try { FileOutputStream out new FileOutputStream( name .class ); out.write( data ); out.close(); } catch( Exception e ) { e.printStackTrace(); } } } 动态代理内部实现 首先来看看类Proxy的代码实现 Proxy的主要静态变量 // 映射表用于维护类装载器对象到其对应的代理类缓存 private static Map loaderToCache new WeakHashMap(); // 标记用于标记一个动态代理类正在被创建中 private static Object pendingGenerationMarker new Object(); // 同步表记录已经被创建的动态代理类类型主要被方法 isProxyClass 进行相关的判断 private static Map proxyClasses Collections.synchronizedMap(new WeakHashMap()); // 关联的调用处理器引用 protected InvocationHandler h; Proxy的构造方法 // 由于 Proxy 内部从不直接调用构造函数所以 private 类型意味着禁止任何调用 private Proxy() {} // 由于 Proxy 内部从不直接调用构造函数所以 protected 意味着只有子类可以调用 protected Proxy(InvocationHandler h) {this.h h;} Proxy静态方法newProxyInstance public static Object newProxyInstance(ClassLoader loader, Class?[]interfaces,InvocationHandler h) throws IllegalArgumentException { // 检查 h 不为空否则抛异常if (h null) { throw new NullPointerException(); } // 获得与指定类装载器和一组接口相关的代理类类型对象Class cl getProxyClass(loader, interfaces); // 通过反射获取构造函数对象并生成代理类实例try { Constructor cons cl.getConstructor(constructorParams); return (Object) cons.newInstance(new Object[] { h }); } catch (NoSuchMethodException e) { throw new InternalError(e.toString()); } catch (IllegalAccessException e) { throw new InternalError(e.toString()); } catch (InstantiationException e) { throw new InternalError(e.toString()); } catch (InvocationTargetException e) { throw new InternalError(e.toString()); } } 类Proxy的getProxyClass方法调用ProxyGenerator的 generateProxyClass方法产生ProxySubject.class的二进制数据 public static byte[] generateProxyClass(final String name, Class[] interfaces) 我们可以import sun.misc.ProxyGenerator调用 generateProxyClass方法产生binary data然后写入文件最后通过反编译工具来查看内部实现原理。 反编译后的ProxySubject.java Proxy静态方法newProxyInstance import java.lang.reflect.*; public final class ProxySubject extends Proxy implements Subject { private static Method m1; private static Method m0; private static Method m3; private static Method m2; public ProxySubject(InvocationHandler invocationhandler) { super(invocationhandler); } public final boolean equals(Object obj) { try { return ((Boolean)super.h.invoke(this, m1, new Object[] { obj })).booleanValue(); } catch(Error _ex) { } catch(Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final int hashCode() { try { return ((Integer)super.h.invoke(this, m0, null)).intValue(); } catch(Error _ex) { } catch(Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final void doSomething() { try { super.h.invoke(this, m3, null); return; } catch(Error _ex) { } catch(Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final String toString() { try { return (String)super.h.invoke(this, m2, null); } catch(Error _ex) { } catch(Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } static { try { m1 Class.forName(java.lang.Object).getMethod(equals, new Class[] { Class.forName(java.lang.Object) }); m0 Class.forName(java.lang.Object).getMethod(hashCode, new Class[0]); m3 Class.forName(Subject).getMethod(doSomething, new Class[0]); m2 Class.forName(java.lang.Object).getMethod(toString, new Class[0]); } catch(NoSuchMethodException nosuchmethodexception) { throw new NoSuchMethodError(nosuchmethodexception.getMessage()); } catch(ClassNotFoundException classnotfoundexception) { throw new NoClassDefFoundError(classnotfoundexception.getMessage()); } } } ProxyGenerator内部是如何生成class二进制数据可以参考源代码。 private byte[] generateClassFile() { /* * Record that proxy methods are needed for the hashCode, equals, * and toString methods of java.lang.Object. This is done before * the methods from the proxy interfaces so that the methods from * java.lang.Object take precedence over duplicate methods in the * proxy interfaces. */ addProxyMethod(hashCodeMethod, Object.class); addProxyMethod(equalsMethod, Object.class); addProxyMethod(toStringMethod, Object.class); /* * Now record all of the methods from the proxy interfaces, giving * earlier interfaces precedence over later ones with duplicate * methods. */ for (int i 0; i interfaces.length; i) { Method[] methods interfaces[i].getMethods(); for (int j 0; j methods.length; j) { addProxyMethod(methods[j], interfaces[i]); } } /* * For each set of proxy methods with the same signature, * verify that the methods return types are compatible. */ for (ListProxyMethod sigmethods : proxyMethods.values()) { checkReturnTypes(sigmethods); } /* * Step 2: Assemble FieldInfo and MethodInfo structs for all of * fields and methods in the class we are generating. */ try { methods.add(generateConstructor()); for (ListProxyMethod sigmethods : proxyMethods.values()) { for (ProxyMethod pm : sigmethods) { // add static field for methods Method object fields.add(new FieldInfo(pm.methodFieldName, Ljava/lang/reflect/Method;, ACC_PRIVATE | ACC_STATIC)); // generate code for proxy method and add it methods.add(pm.generateMethod()); } } methods.add(generateStaticInitializer()); } catch (IOException e) { throw new InternalError(unexpected I/O Exception); } /* * Step 3: Write the final class file. */ /* * Make sure that constant pool indexes are reserved for the * following items before starting to write the final class file. */ cp.getClass(dotToSlash(className)); cp.getClass(superclassName); for (int i 0; i interfaces.length; i) { cp.getClass(dotToSlash(interfaces[i].getName())); } /* * Disallow new constant pool additions beyond this point, since * we are about to write the final constant pool table. */ cp.setReadOnly(); ByteArrayOutputStream bout new ByteArrayOutputStream(); DataOutputStream dout new DataOutputStream(bout); try { /* * Write all the items of the ClassFile structure. * See JVMS section 4.1. */ // u4 magic; dout.writeInt(0xCAFEBABE); // u2 minor_version; dout.writeShort(CLASSFILE_MINOR_VERSION); // u2 major_version; dout.writeShort(CLASSFILE_MAJOR_VERSION); cp.write(dout); // (write constant pool) // u2 access_flags; dout.writeShort(ACC_PUBLIC | ACC_FINAL | ACC_SUPER); // u2 this_class; dout.writeShort(cp.getClass(dotToSlash(className))); // u2 super_class; dout.writeShort(cp.getClass(superclassName)); // u2 interfaces_count; dout.writeShort(interfaces.length); // u2 interfaces[interfaces_count]; for (int i 0; i interfaces.length; i) { dout.writeShort(cp.getClass( dotToSlash(interfaces[i].getName()))); } // u2 fields_count; dout.writeShort(fields.size()); // field_info fields[fields_count]; for (FieldInfo f : fields) { f.write(dout); } // u2 methods_count; dout.writeShort(methods.size()); // method_info methods[methods_count]; for (MethodInfo m : methods) { m.write(dout); } // u2 attributes_count; dout.writeShort(0); // (no ClassFile attributes for proxy classes) } catch (IOException e) { throw new InternalError(unexpected I/O Exception); } return bout.toByteArray(); 总结 一个典型的动态代理创建对象过程可分为以下四个步骤 1、通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler new InvocationHandlerImpl(...); 2、通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类 Class clazz Proxy.getProxyClass(classLoader,new Class[]{...}); 3、通过反射机制获取动态代理类的构造函数其参数类型是调用处理器接口类型 Constructor constructor clazz.getConstructor(new Class[]{InvocationHandler.class}); 4、通过构造函数创建代理类实例此时需将调用处理器对象作为参数被传入 Interface Proxy (Interface)constructor.newInstance(new Object[] (handler)); 为了简化对象创建过程Proxy类中的newInstance方法封装了2~4只需两步即可完成代理对象的创建。 生成的ProxySubject继承Proxy类实现Subject接口实现的Subject的方法实际调用处理器的invoke方法而invoke方法利用反射调用的是被代理对象的的方法Object resultmethod.invoke(proxied,args) 美中不足 诚然Proxy已经设计得非常优美但是还是有一点点小小的遗憾之处那就是它始终无法摆脱仅支持interface代理的桎梏因为它的设计注定了这个遗憾。回想一下那些动态生成的代理类的继承关系图它们已经注定有一个共同的父类叫Proxy。Java的继承机制注定了这些动态代理类们无法实现对class的动态代理原因是多继承在Java中本质上就行不通。有很多条理由人们可以否定对 class代理的必要性但是同样有一些理由相信支持class动态代理会更美好。接口和类的划分本就不是很明显只是到了Java中才变得如此的细化。如果只从方法的声明及是否被定义来考量有一种两者的混合体它的名字叫抽象类。实现对抽象类的动态代理相信也有其内在的价值。此外还有一些历史遗留的类它们将因为没有实现任何接口而从此与动态代理永世无缘。如此种种不得不说是一个小小的遗憾。但是不完美并不等于不伟大伟大是一种本质Java动态代理就是佐例。 参考资料 1、JDK动态代理实现原理 2、Java动态代理机制分析及扩展
http://wiki.neutronadmin.com/news/366559/

相关文章:

  • 网站建设服务公司连云港公司网站优化服务
  • 网站架设的结构简单网页图片
  • 织梦cms如何做网站岳阳市 网站建设
  • 简单的网站首页模板如何注册新账号
  • 东莞做网站哪家公司好湖南省郴州市宜章县邮政编码
  • 免费域名服务西安seo网站设计公司
  • 网站开发技术服务合同范本网站产品详情页怎么做的
  • 可以建设网站便宜网站建设模板网站
  • 做论坛网站杭州大型网站建设
  • 糕点网站设计未备案运行网站
  • 设计吧 网站拼多多网络营销模式
  • 贵州省建设学校网站首页桂林论坛爆料
  • 1元涨1000粉丝网站wordpress文章列表缩略图
  • 网站建设有那些内容优秀网页案例分析
  • php+mysql 网站建设做视频网站注意什么问题
  • 做搜索引擎的网站有哪些大兴安岭商城网站开发设计
  • 做技术分享网站有哪些万维网域名注册网站
  • 网站开发类论文题目网站制作做网站
  • 县区网站服务器机房建设为什么大家用wordpress建网站
  • 免费域名映射南宁百度seo网站优化
  • 神马搜索推广西安官网优化技术
  • 合肥网站建设报价西安未央区今天出啥事了
  • 濮阳网站建设熊掌号力软框架做网站
  • php网站开发图文教程机场建设集团网站
  • 广州建设厅官方网站邵阳营销型网站建设
  • 学做网站必须php吗网上学设计的培训机构
  • 如何制作手机网页最简单的方法长春网站快速优化排名
  • 厦门响应式网站建设广州营销型网站制作
  • 电商公司网站建设财务核算wordpress 多色主题
  • 网站开发都是用什么框架河北seo搜索引擎优化