Java_静态代理和动态代理

Java_静态代理和动态代理
Java_静态代理和动态代理

Java 静态代理和动态代理

Java 2010-10-16 17:22:21 阅读129 评论0 字号:大中小订阅代理模式主要有两种:静态代理和动态代理

1. 静态代理:

比如要在输出“HelloWorld”前打印一个字符串“Welcome”

2.动态代理

动态代理与静态代理相比较,最大的好处是接口中声明的所有方法都被转移到一个集中的方法中处理(invoke),而不需要像静态代理那样对接口的每一个方法进行中转。

动态代理类只能代理接口,代理类都需要实现InvocationHandler接口,覆盖invoke方法。该invoke方法就是调用被代理接口的所有方法时需要调用的。

在测试类里调用实现类的print和say方法,因为代理类里代理了HelloWorld的所有方法。所以就不需要像静态代理类那样一一实现了。

动态代理

动态代理 简单介绍 代理可分为静态代理和动态代理。静态代理在源代码级实现,而动态代理在运行时实现。 代理的几个概念: 抽象角色:声明真实对象和代理对象的共同接口。(就是接口) 代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。(就是实现上述接口的代理,即代理对象)真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。(就是要代理的真正对象,即被代理对象,或称目标对象) 在使用JDK中的动态代理时,要注意目标对象必须实现接口。动态代理的几个概念: 动态代理类:实现了一系列的接口,而这些接口是在动态代理类被创建时指定的。 代理接口:就是由动态代理类所实现的接口。 代理实例:就是动态代理类的实例。 动态代理类和其实例可以由https://www.360docs.net/doc/247432412.html,ng.reflect.Proxy来创建。如要创造接口Foo的代理: InvocationHandler handler = new MyInvocationHandler(...); //创建动态代理类 Class proxyClass = Proxy.getProxyClass( Foo.class.getClassLoader(), new Class[] { Foo.class }); //创建动态代理类的实例 Foo f = (Foo) proxyClass. getConstructor(new Class[] { InvocationHandler.class }). newInstance(new Object[] { handler }); 或者使用(更简单,一步完成创建动态代理类的实现): Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class[] { Foo.class }, handler); 实例演示 DynamicProxy.java

JAVA的反射机制与动态代理

JA V A的反射机制与动态代理 李海峰(QQ:61673110)-Andrew830314@https://www.360docs.net/doc/247432412.html, 运行时类型信息(RunTime Type Information,RTTI)使得你在程序运行时发现和使用类型信息。RTTI主要用来运行时获取向上转型之后的对象到底是什么具体的类型。 1.Class对象: JAVA使用Class对象来执行RTTI。每个类都有一个Class对象,它用来创建这个类的所有对象,反过来说,每个类的所有对象都会关联同一个Class对象(对于数组来说,维数、类型一致的数组的Class对象才是相同的),每个对象的创建都依赖于Class对象的是否创建,Class对象的创建发生在类加载(https://www.360docs.net/doc/247432412.html,ng.ClassLoader)的时候。 https://www.360docs.net/doc/247432412.html,ng.Class类实现了Serializable、GenericDeclaration、Type、AnnotatedElement四个接口,分别实现了可序列化、泛型定义、类型、元数据(注解)的功能。 你可以把Class对象理解为一个类在内存中的接口代理(它代理了这个类的类型信息、方法签名、属性),JVM加载一个类的时候首先创建Class对象,然后创建这个类的每个实例的时候都使用这个Class对象。 Class只有一个私有的无参构造方法,也就是说Class的对象创建只有JVM可以完成。 如何验证同一个类的多个对象的Class对象是一个呢? Cf1 cf1 = new Cf1(); Class clazz = Cf1.class; System.out.println(cf1.getClass() == clazz); 我们知道==用来比较引用是否相等(也就是同一个引用),上面的输出语句结果是true。那么Class对象是否相等是JAVA对象中唯一可以使用==判断的。 如何获取Class对象: 1.所有的引用数据类型(类-类型)的类名、基本数据类型都可以通过.class方式获取其Class 对象(对于基本数据类型的封装类还可以通过.TYPE的方式获取其Class对象,但要注意.TYPE实际上获取的封装类对应的基本类型的Class对象的引用,那么你可以判断出int.class==Integer.TYPE返回true,int.class==Integer.class返回false!),通过这种方式不会初始化静态域,使用.class、.TYPE的方式获取Class对象叫做类的字面常量; 2.Class的forName(String name)传入一个类的完整类路径也可以获得Class对象,但由于使用的是字符串,必须强制转换才可以获取泛型的Class的Class对象,并且你必须获取这个方法可能抛出的ClassNotFoundException异常。 2.对于引用数据类的引用(必须初始化),可以通过Object类继承的getClass()方法获取这个引用的Class对象,由于引用已经被初始化,所以这种方式也不会初始化静态域,因为静态域已经被初始化过。另外,前面两种方式如果说是创建Class对象,那么这种方式应该是取得Class对象,因为类的实例已经被创建,那么Class对象也一定早就被创建。 Class的常用方法: l forName(String name):这是一个静态方法,传入的参数是一个类的完整类路径的字符串,返回这个类的Class对象,前面说过Class对象的创建发生在类的加载时,所以这个方法会导致静态成员被调用; l forName(String name,boolean initialize,ClassLoader loader):这是上面的方

泛型动态代理基础

泛型(Generic) —泛形的作用 JDK5中的泛形允许程序员在编写集合代码时,就限制集合的处理类型,从而把原来程序运行时可能发生问题,转变为编译时的问题,以此提高程序的可读性和稳定性(尤其在大型程序中更为突出)。 注意:泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。 泛形的基本术语,以ArrayList为例:<>念着typeof ArrayList中的E称为类型参数变量 ArrayList中的Integer称为实际类型参数 整个称为ArrayList泛型类型 整个BaseDaoParameterizedType/Type 自定义泛形——泛型类和反射泛形 如果一个类多处都要用到同一个泛型,这时可以把泛形定义在类上(即类级别的泛型),语法格式如下: public class GenericDao { private T field1; public void save(T obj){} public T getId(int id){} } 泛形的典型应用:BaseDao和反射泛型 Annotation(注解) 概述 从JDK 5.0 开始, Java 增加了对元数据(MetaData) 的支持, 也就是Annotation(注解)。 什么是Annotation,以及注解的作用?三个基本的Annotation: @Override: 限定重写父类方法, 该注解只能用于方法 @Deprecated: 用于表示某个程序元素(类, 方法等)已过时 @SuppressWarnings: 抑制编译器警告. Annotation 其实就是代码里的特殊标记, 它用于替代配置文件,也就是说,传统方式通过配置文件告诉类如何运行,有了注解技术后,开发人员可以通过注解告诉类如何运行。在Java 技术里注解的典型应用是:可以通过反射技术去得到类里面的注解,以决定怎么去运行类。掌握注解技术的要点: 如何自定义注解 如何反射注解,并根据反射的注解信息,决定如何去运行类

尚硅谷_动态代理

————————————————————————————— 动态代理原理简析 一、概述 1.动态编译https://www.360docs.net/doc/247432412.html,pilationTask 动态编译想理解自己查API文档 2.反射被代理类主要使用Method.invoke(Object o,Object... args);对带有指定参数的指定对象调用由此Method 对象表示的底层方法。 3.类的加载URLClassLoader可以加载硬盘任意位置的.java文件。class.getClassLoader只能加载classPath目录下的类。 动态代理可以理解为动态生成发射代理的类。这其中可以动态增加逻辑操作。比如日志的打印,事物的处理等。spring的AOP操作也是动态代理的。 二、创建业务接口 假设我们有一个接口GrowAble可成长的。 1.package https://www.360docs.net/doc/247432412.html,; 2. 3.public interface GrowAble { 4. void growUp(); 5.} 一棵小树苗实现了这个接口 1.package https://www.360docs.net/doc/247432412.html,; 2.public class Tree implements GrowAble { 3. @Override 4. public void growUp() { 5. System.out.println('I am a tree , I'm grow up!'); 6. } 7. 8.} 这时我们想不在不改变源码的情况下想知道树长了多少这个操作? 我们需要一个转换接口。

————————————————————————————— 1.package https://www.360docs.net/doc/247432412.html,; 2.import https://www.360docs.net/doc/247432412.html,ng.reflect.Method; 3. 4.public interface InvactionHandle { 5. void invoke(Object o,Method m); 6.} 一个实现接口类。 01.package https://www.360docs.net/doc/247432412.html,; 02.import https://www.360docs.net/doc/247432412.html,ng.reflect.Method; 03.import java.util.Random; 04. 05.public class HeightInvactionHandle implements InvactionHandle { 06. @Override 07. public void invoke(Object c, Method m) { 08. try { 09. m.invoke(this.o); 10. System.out.println('这棵树长了' + new Random().nextInt(9527)+'米!!!' ); 11. } catch (Exception e) { 12. e.printStackTrace(); 13. } 14. } 15. private Object o; 16. public HeightInvactionHandle(Object o) { 17. super(); 18. this.o = o; 19. } 20.} 三、其他重要类 现在最重要的Proxy类了。把上述两个接口接口起来。 01.package https://www.360docs.net/doc/247432412.html,;

proxy-动态代理深度学习

一.相关类及其方法: https://www.360docs.net/doc/247432412.html,ng.reflect.Proxy, Proxy 提供用于创建动态代理类和实例的静态方法. newProxyInstance() 返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序 (详见api文档) https://www.360docs.net/doc/247432412.html,ng.reflect.InvocationHandler, InvocationHandler 是代理实例的调用处理程序实现的接口。 invoke() 在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。 (详见api文档) 二.源代码: 被代理对象的接口及实现类: package com.ml.test; public interface Manager { public void modify(); } package com.ml.test; public class ManagerImpl implements Manager { @Override public void modify() {

System.out.println("*******modify()方法被调用"); } } 业务代理类: package com.ml.test; import https://www.360docs.net/doc/247432412.html,ng.reflect.InvocationHandler; import https://www.360docs.net/doc/247432412.html,ng.reflect.Method; public class BusinessHandler implements InvocationHandler { private Object object = null; public BusinessHandler(Object object) { this.object = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("do something before method"); Object ret = method.invoke(this.object, args); System.out.println("do something after method"); return ret; } }

Java反射机制与动态代理

前言,在Java运行时刻,能否知道一个类的属性方法并调用改动之?对于任意一个对象,能否知道他的所属类,并调用他的方法?答案是肯定的。这种动态的获取信息及动态调用方法的机制在Java中称为“反射”(reflection)。 Java反射机制主要提供以下功能: 在运行时判断任意一个对象所属的类; 在运行时构造任意一个类的对象; 在运行时判断任意一个类所具有的成员变量和方法; 在运行时调用任意一个对象的方法。 Reflection 是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等等)、superclass(例如Object)、实现之interfaces(例如Serializable),也包括fields和methods的所有信息,并可于运行时改变fields内容或调用methods。 一般而言,开发者社群说到动态语言,大致认同的一个定义是:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。 在JDK中,主要由以下类来实现Java反射机制,这些类都位于 https://www.360docs.net/doc/247432412.html,ng.reflect包中: Class类:代表一个类; Field 类:代表类的成员变量(成员变量也称为类的属性); Method类:代表类的方法; Constructor 类:代表类的构造方法; Array类:提供了动态创建数组,以及访问数组的元素的静态方法; 例程DateMethodsTest类演示了Reflection API的基本作用,它读取命令行参数指定的类名,然后打印这个类所具有的方法信息,代码如下: Java代码 1.public class DateMethodsTest 2.{ 3. public static void main(String args[]) throws Exception 4. { 5. // 加载并初始化命令行参数指定的类 6. Class classType = Class.forName("java.util.Date"); 7. // 获得类的所有方法 8. Method methods[] = classType.getDeclaredMethods(); 9. for (int i = 0; i < methods.length; i++) 10. { 11. System.out.println(methods[i].toString());

java动态代理实现Authorization(授权)

动态代理实现Authorization(授权) * https://www.360docs.net/doc/247432412.html,ng.reflect包中的 Proxy和InvocationHandler接口提供了创建(指定类[接口更准确些]的)动态代理类的能力。 我们知道,对象是类的实例,一般使用内存来模拟对象,对象是依据类为模板来创建的,创建时使用new来分配一块内存区(其布局 参考相应类的内存布局),为变量做一些赋值便是对象的初始化了。我们知道通常类是设计时的产物,在设计时我们编写对象的模板(即——类),运行时 产生类的实例。类所处的文件是 .java文件——源文件,之后编译为jvm-----java虚拟机可解释执行的.class字节码文件,在类解析 过程中这些.class文件由类加载器加载到虚拟机(可实现自己的类加载器来加载处于特定路径下的类,或加载用某种加密算法加密过的类文件---这样 便于进行安全控制——具体描述参考(Core java ——Java核心卷二))。在遇到创建对象的指令时使用加载的类来创建对象内存 空间。动态代理是不用创建类文件(当然也不用创建java源文件),就能在虚拟机中构造出类文件区域来(相当于使用Proxy类来 创建一块类内存区域,该区域中的内容相当于加载某个.class文件产生的区域;比如我们在使用DOM技术时,从一个XML文件构造一个 DOM内存表示,它是XML文件的内存表示,但我们也可以直接使用DOM API在内存中构建一个dom树,最终结果就是一个内存DOM树,你不用关心 这个dom树是来自于xmL文件还是直接的运行时构造)。 * ** 关于代理设计模式,这里不再敷述。代理和被代理类(目标类)实现共同的接口。我们在调用时不需区别它是否是真正的目标对象。 代理会转发请求到目标对象的。比如互联网上的代理服务器,我们不必关心它是不是代理,就当它不存在一样。对客户调用端 他是不关心具体是谁来提供这个服务功能;在服务端选择使用代理的原因可能是:安全,日志,防火墙等。就是说代理可提供一些 非功能性功能,比如缓存功能____来加速服务的响应的速度。在面向方面技术(AOP)中这些非功能性需求被称作“方面”他们横切于功能类 的实现中,比如:某个SubServerImpl(子服务实现)中的某个服务方法: subServer.doService(){ //在日志输出中常有类似的代码出现于多个类实现中 loger.log(""); } 如果已经存在了一个服务实现,你还需要加入日志功能,而又不想改动既有的实现,也不想太多的改动客户端,我们可以引入

Java动态代理的实现

动态代理,代理类需要实现接口https://www.360docs.net/doc/247432412.html,ng.reflect.InvocationHandler 接口UserDao public interface UserDao { void addUser(); void deleteUser(); } 两个普通的实现 public class UserDaoOracleImpl implements UserDao { @Override public void addUser() { System.out.println("UserDaoOracleImpl.addUser()"); } @Override public void deleteUser() { System.out.println("UserDaoOracleImpl.deleteUser()"); } } public class UserDaoMySqlImpl implements UserDao { @Override public void addUser() { System.out.println("UserDaoMySqlImpl.addUser()"); } @Override public void deleteUser() { System.out.println("UserDaoMySqlImpl.deleteUser()"); } } 代理的接口实现 public class UserDaoDynamicProxy implements InvocationHandler { private Object target; public Object getProxyInstance(Object target){ this.target = target; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object obj = null; obj = method.invoke(this.target, args); return null; }

Java设计模式之代理模式

Java设计模式之代理模式 引言 Java 动态代理机制的出现,使得Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类。代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架。通过阅读本文,读者将会对Java 动态代理机制有更加深入的理解。本文首先从Java 动态代理的运行机制和特点出发,对其代码进行了分析,推演了动态生成类的内部实现。 代理:设计模式 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。 图1. 代理模式 为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别。通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间,从而在设计上获得了更大的灵活性。Java 动态代理机制以巧妙的方式近乎完美地实践了代理模式的设计理念。 相关的类和接口 要了解Java 动态代理的机制,首先需要了解以下相关的类或接口: https://www.360docs.net/doc/247432412.html,ng.reflect.Proxy:这是Java 动态代理机制的主类,它提供了一组静态方法来为一组接口动态地生成代理类及其对象。

由图可见,Proxy 类是它的父类,这个规则适用于所有由Proxy 创建的动态代理类。而且该类还实现了其所代理的一组接口,这就是为什么它能够被安全地类型转换到其所代理的某接口的根本原因。

Java 动态代理机制分析及扩展

引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类。代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能,这是一套非常灵活有弹性的代理框架。通过阅读本文,读者将会对 Java 动态代理机制有更加深入的理解。本文首先从 Java 动态代理的运行机制和特点出发,对其代码进行了分析,推演了动态生成类的内部实现。 代理:设计模式 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。 图 1. 代理模式 为了保持行为的一致性,代理类和委托类通常会实现相同的接口,所以在访问者看来两者没有丝毫的区别。通过代理类这中间一层,能有效控制对委托类对象的直接访问,也可以很好地隐藏和保护委托类对象,同时也为实施不同控制策略预留了空间,从而在设计上获得了更大的灵活性。Java 动态代理机制以巧妙的方式近乎完美地实践了代理模式的设计理念。 相关的类和接口 要了解 Java 动态代理的机制,首先需要了解以下相关的类或接口: https://www.360docs.net/doc/247432412.html,ng.reflect.Proxy:这是 Java 动态代理机制的主类,它提供了一组静态方法来为一组接口动态地生成代理类及其对象。 清单 1. Proxy 的静态方法

?https://www.360docs.net/doc/247432412.html,ng.reflect.InvocationHandler:这是调用处理器接口,它自定义了一个 invoke 方法,用于集中处理在动态代理类对象上的方法调用,通常在该方法中实现对委托类的代理访问。 清单 2. InvocationHandler 的核心方法 每次生成动态代理类对象时都需要指定一个实现了该接口的调用处理器对象(参见 Proxy 静态方法 4 的第三个参数)。 ?https://www.360docs.net/doc/247432412.html,ng.ClassLoader:这是类装载器类,负责将类的字节码装载到 Java 虚拟机(JVM)中并为其定义类对象,然后该类才能被使用。Proxy 静态方法生成动态代理类同样需要通过类装载器来进行装载才能使用,它与普通类的唯一区别就是其字节码是由 JVM 在运行时动态生成的而非预存在于任何一个 .class 文件中。 每次生成动态代理类对象时都需要指定一个类装载器对象(参见 Proxy 静态方法 4 的第一个参数) 代理机制及其特点 首先让我们来了解一下如何使用 Java 动态代理。具体有如下四步骤: 1.通过实现 InvocationHandler 接口创建自己的调用处理器; 2.通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类; 3.通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型; 4.通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。 清单 3. 动态代理对象创建过程

动态代理模式

package com.bjsxt.proxy; import java.util.Random; public class Tank implements Moveable { @Override public void move() { System.out.println("Tank Moving..."); try { Thread.sleep(new Random().nextInt(10000)); // 表明tank正在移动中 } catch (InterruptedException e) { e.printStackTrace(); } } } 想知道看此段代码运行了多长时间。 方法里面运行的时间。 一个类里面有另外一个类的对象,这叫做聚合 一个用继承实现此功能,一个用聚合实现此功能。 聚合好,继承不灵活 记录日志、记录时间、记录权限的控制 用继承的方式会无限制的迭加下去。类爆炸现象!!!

代理之间互相的组合!因为共同实现的是Movable接口!! 关键是实现同一接口! 这是静态代理! 先日志、后时间还是先时时间,还是日志 代理的类根据需求还可能无限膨胀下去。 动态代理解决类太多的问题! 实现动态的编译:/JDK6 Complier API, CGLib, ASM 代理的总代理 深入java虚拟机----二进制代码的实现。 被代理的类都实现了一种结果!!继承也能实现,但是不推荐使用!! 1 实现 package https://www.360docs.net/doc/247432412.html,piler.test;

import java.io.File; import java.io.FileWriter; import https://www.360docs.net/doc/247432412.html,ng.reflect.Constructor; import https://www.360docs.net/doc/247432412.html,.URL; import https://www.360docs.net/doc/247432412.html,.URLClassLoader; import javax.tools.JavaCompiler; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; import https://www.360docs.net/doc/247432412.html,pilationTask; import com.bjsxt.proxy.Moveable; import com.bjsxt.proxy.Tank; public class Test1 { public static void main(String[] args) throws Exception{ String rt = "\r\n"; String src = "package com.bjsxt.proxy;" + rt + "public class TankTimeProxy implements Moveable {" + rt + " public TankTimeProxy(Moveable t) {" + rt + " super();" + rt + " this.t = t;" + rt + " }" + rt + " Moveable t;" + rt + " @Override" + rt + " public void move() {" + rt + " long start = System.currentTimeMillis();" + rt + " System.out.println(\"starttime:\" + start);" + rt +

java - 用Java动态代理实现AOP

用Java动态代理实现AOP 目前整个开发社区对AOP(Aspect Oriented Programing)推崇备至,也涌现出大量支持AOP 的优秀Framework,--Spring, JAC, Jboss AOP 等等。AOP似乎一时之间成了潮流。Java初学者不禁要发出感慨,OOP还没有学通呢,又来AOP。本文不是要在理论上具体阐述何为AOP, 为何要进行AOP . 要详细了解学习AOP可以到它老家https://www.360docs.net/doc/247432412.html,去瞧瞧。这里只是意图通过一个简单的例子向初学者展示一下如何来进行AOP. 为了简单起见,例子没有没有使用任何第三方的AOP Framework, 而是利用Java语言本身自带的动态代理功能来实现AOP. 让我们先回到AOP本身,AOP主要应用于日志记录,性能统计,安全控制,事务处理等方面。它的主要意图就要将日志记录,性能统计,安全控制等等代码从商业逻辑代码中清楚的划分出来,我们可以把这些行为一个一个单独看作系统所要解决的问题,就是所谓的面向问题的编程(不知将AOP译作面向问题的编程是否欠妥)。通过对这些行为的分离,我们希望可以将它们独立地配置到商业方法中,而要改变这些行为也不需要影响到商业方法代码。 假设系统由一系列的BusinessObject所完成业务逻辑功能,系统要求在每一次业务逻辑处理时要做日志记录。这里我们略去具体的业务逻辑代码。 public interface BusinessInterface { public void processBusiness(); } public class BusinessObject implements BusinessInterface { private Logger logger = Logger.getLogger(this.getClass().getName()); public void processBusiness(){ try { https://www.360docs.net/doc/247432412.html,("start to processing..."); //business logic here. System.out.println(“here is business logic”); https://www.360docs.net/doc/247432412.html,("end processing..."); } catch (Exception e){ https://www.360docs.net/doc/247432412.html,("exception happends..."); //exception handling } } } 这里处理商业逻辑的代码和日志记录代码混合在一起,这给日后的维护带来一定的困难,并且也会造成大量的代码重复。完全相同的log代码将出现在系统的每一个BusinessObject中。

Java动态代理技术

Java动态代理技术 现在Java的好多应用都使用动态代理,包括Hibernate,Spring等等都使用动态代理技术。 动态代理就是在没有Java文件的情况下生成符合格式的Java字节码,再定义成类对象来使用。 动态代理有两种实现方式,一种是基于接口的实现方式,另一种当然是不基于接口的实现,下面 就两种方式的实现方法简单说一说。 基于接口的实现: 这种实现方式主要利用Java的反射机制,通过指定的接口动态生成实现指定接口的类来实 现,需要用到https://www.360docs.net/doc/247432412.html,ng.reflect.InvocationHandler接口和https://www.360docs.net/doc/247432412.html,ng.reflect.Proxy类。首 先编写一个类实现InvocationHandler接口的invoke方法: public class MyInvocationHandler implements InvocationHandler{ public Object invoke(Object proxy, Method method, Object[] args) { …… } } InvocationHandler handler = new MyInvocationHandler(...); Class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(),new Class[] { Foo.class }); Foo f = (Foo) proxyClass.getConstructor(new Class[] { InvocationHandler.class }). newInstance(new Object[] { handler }); 或者直接生成代理对象使用如下方法: Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[] { Foo.class }, handler); 动态代理类(以下简称为代理类)是一个实现在创建类时在运行时指定的接口列表的类, 该类具有下面描述的行为。代理接口是代理类实现的一个接口。代理实例是代理类的一个实 例。每个代理实例都有一个关联的调用处理程序对象,它可以实现接口InvocationHandler。通 过其中一个代理接口的代理实例上的方法调用将被指派到实例的调用处理程序的Invoke方法, 并传递代理实例、识别调用方法的https://www.360docs.net/doc/247432412.html,ng.reflect.Method对象以及包含参数的Object类型的 数组。调用处理程序以适当的方式处理编码的方法调用,并且它返回的结果将作为代理实例上方 法调用的结果返回。

Java动态代理

动态代理模式使用 关键字: proxy 动态代理 jdk文档: 写道 动态代理类(以下简称为代理类)是一个实现在创建类时在运行时指定的接口列表的类,该类具有下面描述的行为。代理接口是代理类实现的一个接口。代理实例是代理类的一个实例。每个代理实例都有一个关联的调用处理程序对象,它可以实现接口 InvocationHandler。通过其中一个代理接口的代理实例上的方法调用将被指派到实例的调用处理程序的 Invoke 方法,并传递代理实例、识别调用方法的 https://www.360docs.net/doc/247432412.html,ng.reflect.Method 对象以及包含参数的 Object 类型的 数组。调用处理程序以适当的方式处理编码的方法调用,并且它返回的结果将作为代理实例上方法调用的结果返回。 测试代码如下: 一个接口:MyInterface Java代码 1.public interface MyInterface { 2.public void print(); 3.public void test(int num); 4.} 实现以上接口的类:MyTest Java代码 1.public class MyTest implements MyInterface{ 2.public void print(){ 3. System.out.println("MyTest print"); 4.} 5.public void test(int num){ 6. System.out.println(num); 7.} 8.}

处理类:MyTestHandler Java代码 1.public class MyTestHandler implements InvocationHandler { 2. 3. private MyInterface mytest = null; 4. 5. public MyInterface bind(MyInterface test) { //注意传递的参 数类型是接口,而不是实现类 6. this.mytest = test; 7. MyInterface proxyTest = (MyInterface) Proxy.newProxyIns tance(test.getClass().getClassLoader(), test.getClass().getInte rfaces(), this); 8. return proxyTest; 9. } 10. 11. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //具体的处理策略,根据方法名判断 12. Object obj = null; 13. if ("print".equals(method.getName())) { 14. System.out.println("got it"); 15. } else if ("test".equals(method.getName())) { 16. int num = (Integer)args[0]; 17. System.out.println(num+2); 18. } else { 19. obj = method.invoke(mytest, args); //交给目标对象 处理 20. } 21. return obj; 22. } 23.} 测试类:Main Java代码 1.public class Main { 2.public static void main(String args[]){ 3.MyTest test = new MyTest(); 4.MyTestHandler handler = new MyTestHandler();

C#实现动态代理

[转]基于Dynamic Proxy技术的方法拦截器开发 来自<>代理技术--代码变得更简洁 在面向对象编程中,会用到大量的类,并且会多次调用类中的方法。有时可能需要对这些方法的调用进行一些控制。如在权限管理中,一些用户没有执行某些方法的权限。又如在日志系统中,在某个方法执行完后,将其执行的结果记录在日志中。处理这些需求的一般做法是在调用这些方法的地方加上适当的代码。如以下C#代码如示: public class Class1 { public void MyMethod() { ... } static void Main() { Class1 c1 = new Class1(); if(permit()) { c1.MyMethod(); logger(); } } } 在以上代码中,permit()是一个得到MyMethod方法执行权限的函数,如果MyMethod方法可以被执行,那么permit()返回true,否则,返回false。logger()是记录日志的函数。 我们可以看出,在这段程序中存在一个问题,就是它的主要功能是执行MyMethod方法,至于权限控制以及日志功能只是它的次要功能(这里说它们是次要功能,并不是说它们不重要,而是说没有这些功能并不影响程序的核心功能的执行)。而将这些次要功能和程序的主要业务逻辑混在一起,如果程序所涉及的类比较多的话,这些次要功能的代码将和业务逻辑代码紧密地结合在一起,这样在修改某一部分时(比如换一个写日志的函数),必须要修改大量的代码。而且程序员在考虑业务逻辑的同时,还要关注这些次要功能,从而无法将精力集中在业务逻辑上。

利用Java的反射与代理实现IOC模式

在Java中,其反射和动态代理机制极其强大,我们可以通过其反射机制在运行时获取信息。而代理是一种基本的设计模式,它是一种为了提供额外的或不同的操作而插入到真实对象中的某个对象。而Java的动态代理在代理上更进一步,既能动态的创建代理对象,又能动态的调用代理方法。Java的反射和动态代理机制,使Java变得更加强大。 Spring框架这几年风头正劲,虽然使用者众多,但真正了解其内部实现原理的朋友却并不是很多。其实,了解它的内部实现机制和设计思想是很有必要的大家都知道,Spring框架的IOC和AOP部分功能强大,很值得我们学习。那么让我们在这两篇文章中分别详细的学习IOC 和AOP的实现吧。 在本文中,主要讲述的是用Java的反射机制实现IOC。下面,让我们开始IOC之旅吧!一.Java反射机制概述与初探 Java的反射机制是Java语言的一个重要特性,Java具有的比较突出的动态机制就是反射(reflection)。通过它,我们可以获取如下信息: 1)在运行时判断任意一个对象所属的类; 2)在运行时获取类的对象; 3)在运行时获得类所具有的成员变量和方法等。 下面让我们通过调用一个Java Reflection API的演示实例来见识一下反射机制的强大。 首先在IDE中建立名为reflection_proxy的Java工程,并建立存放源文件的目录src,并在src目录下分别建立org.amigo. reflection目录和org.amigo.proxy目录来分别存放代理和反射的实例。我们在reflection目录下建立ReflectionTest.java文件,在该文件中编写代码来演示Java Reflection API的使用。该类的代码如下所示: package org.amigo.reflection; import java.awt.Button; import https://www.360docs.net/doc/247432412.html,ng.reflect.Method; import java.util.Hashtable; /** *初探Java的反射机制. *@authorAmigoXie *Creationdate:2007-10-2-上午10:13:48 */ publicclass ReflectionTest { /** *@param args */ publicstaticvoid main(String[] args) throws Exception { ReflectionTest reflection = new ReflectionTest(); reflection.getNameTest(); System.out.println(""); reflection.getMethodTest(); } /**

相关文档
最新文档