`
lorry1113
  • 浏览: 262436 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

动态创建代理(转)

    博客分类:
  • java
阅读更多
随着Proxy的流行,Sun把它纳入到JDK1.3实现了Java的动态代理。动态代理和普通的代理模式的区别,就是动态代理中的代理类是由 java.lang.reflect.Proxy类在运行期时根据接口定义,采用Java反射功能动态生成的。和 java.lang.reflect.InvocationHandler结合,可以加强现有类的方法实现。如图2,图中的自定义Handler实现 InvocationHandler接口,自定义Handler实例化时,将实现类传入自定义Handler对象。自定义Handler需要实现 invoke方法,该方法可以使用Java反射调用实现类的实现的方法,同时当然可以实现其他功能,例如在调用实现类方法前后加入Log。而Proxy类根据Handler和需要代理的接口动态生成一个接口实现类的对象。当用户调用这个动态生成的实现类时,实际上是调用了自定义Handler的 invoke方法。

Proxy类提供了创建动态代理类及其实例的静态方法。
(1)getProxyClass()静态方法负责创建动态代理类,它的完整定义如下:

public static Class getProxyClass(ClassLoader loader, Class[] interfaces) throws IllegalArgumentException

  参数loader 指定动态代理类的类加载器,参数interfaces 指定动态代理类需要实现的所有接口。

(2)newProxyInstance()静态方法负责创建动态代理类的实例,它的完整定义如下:

public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler handler) throws
     IllegalArgumentException

   参数loader 指定动态代理类的类加载器,参数interfaces 指定动态代理类需要实现的所有接口,参数handler 指定与动态代理类关联的 InvocationHandler 对象。

以下两种方式都创建了实现Foo接口的动态代理类的实例:
/**** 方式一 ****/
//创建InvocationHandler对象
InvocationHandler handler = new MyInvocationHandler(...);

//创建动态代理类
Class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), new Class[] { Foo.class });

//创建动态代理类的实例
Foo foo = (Foo) proxyClass.getConstructor(new Class[] { InvocationHandler.class }).
   newInstance(new Object[] { handler });

/**** 方式二 ****/
//创建InvocationHandler对象
InvocationHandler handler = new MyInvocationHandler(...);

//直接创建动态代理类的实例
Foo foo = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),new Class[] { Foo.class }, handler);

由Proxy类的静态方法创建的动态代理类具有以下特点:
  动态代理类是public、final和非抽象类型的;
  动态代理类继承了java.lang.reflect.Proxy类;
  动态代理类的名字以“$Proxy”开头;
  动态代理类实现getProxyClass()和newProxyInstance()方法中参数interfaces指定的所有接口;

Proxy 类的isProxyClass(Class cl)静态方法可用来判断参数指定的类是否为动态代理类。只有通过Proxy类创建的类才是动态代理类;

动态代理类都具有一个public 类型的构造方法,该构造方法有一个InvocationHandler 类型的参数。

由Proxy类的静态方法创建的动态代理类的实例具有以下特点:
1. 假定变量foo 是一个动态代理类的实例,并且这个动态代理类实现了Foo 接口,那么“foo instanceof Foo”的值为true。把变量foo强制转换为Foo类型是合法的:
(Foo) foo //合法

2.每个动态代理类实例都和一个InvocationHandler 实例关联。Proxy 类的getInvocationHandler(Object proxy)静态方法返回与参数proxy指定的代理类实例所关联的InvocationHandler 对象。

3.假定Foo接口有一个amethod()方法,那么当程序调用动态代理类实例foo的amethod()方法时,该方法会调用与它关联的InvocationHandler 对象的invoke()方法。

InvocationHandler 接口为方法调用接口,它声明了负责调用任意一个方法的invoke()方法:
Object invoke(Object proxy,Method method,Object[] args) throws Throwable

参数proxy指定动态代理类实例,参数method指定被调用的方法,参数args 指定向被调用方法传递的参数,invoke()方法的返回值表示被调用方法的返回值。



最后看一个例子,该例子模仿spring 的IOC原理。
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
class Logic{
public void logic(){
Dao dao = Factory.create();
System.out.println("dynamic proxy's name: "+dao.getClass().getName());
dao.insert();
}
}
class Factory{
static Dao create(){
Dao dao = new JdbcDao();
MyInvocationHandler hand = new MyInvocationHandler();
return (Dao)hand.get(dao);
}
}
interface Dao{
public void update();
public void insert();
}
class JdbcDao implements Dao{
public void update(){
System.out.println("in jdbc update");
}
public void insert(){
System.out.println("in jdbc insert");
}
}
class HibernateDao implements Dao{
public void update(){
System.out.println("in hibernate update");
}
public void insert(){
System.out.println("in hibernate insert");
}
}
class MyInvocationHandler implements InvocationHandler {
Object o;
public Object get(Object o){
System.out.println("in get method of MyInvocationHandler");
this.o = o;
return Proxy.newProxyInstance(o.getClass().getClassLoader(),o.getClass().getInterfaces(),this);
}
public Object invoke(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
System.out.println("write log before invoke");
Object result = arg1.invoke(o, arg2);
System.out.println("write log after invoke");
return result;
}
}
public class Test {
public static void main(String[] args) {
Logic l = new Logic();
l.logic();
}
}


分享到:
评论

相关推荐

    Java静态代理和动态代理

    与静态代理不同,动态代理在程序运行时生成,利用Java的反射API动态创建代理类。动态代理适用于那些在运行时才知道需要代理的对象或者代理行为的情况。Java提供了`java.lang.reflect.Proxy`类和`java.lang.reflect....

    JVM技术,反射与动态代理

    动态代理是Java提供的一种在运行时创建代理对象的技术,主要由java.lang.reflect.Proxy和java.lang.reflect.InvocationHandler两个类实现。动态代理常用于AOP(面向切面编程)和事件监听等场景,如: 1. AOP实现:...

    静态代理与动态代理Demo

    动态代理是在运行时动态创建代理类,它不需要预先知道被代理类的具体实现,而是通过反射机制在运行时根据接口生成对应的代理类。Java中提供了`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`...

    java jdk 动态代理 演示demo

    Java JDK 动态代理是一种强大的特性,它允许我们在运行时创建代理对象,这些代理对象可以扩展或增强已存在的接口实现。动态代理在处理AOP(面向切面编程)场景、事件监听、性能监控等方面有着广泛的应用。下面我们将...

    动态代理和AOP详解

    1. JDK动态代理:如果目标对象实现了接口,Spring会使用`Proxy.newProxyInstance()`创建代理对象,通过`InvocationHandler`执行增强逻辑。 2. CGLIB代理:当目标对象没有实现接口时,Spring会使用CGLIB库生成目标类...

    Jdk动态代理,cglib动态代理,反射和拦截器(链)示例

    动态代理主要用于创建一个代理对象,这个代理对象可以代替原始目标对象执行方法,并在调用前后添加额外的操作。例如,日志记录、性能监控等。InvocationHandler接口定义了一个方法`invoke()`,它在代理对象调用任何...

    动态代理和工厂方法例子

    动态代理是一种在运行时创建代理对象的技术,它可以用来实现如AOP(面向切面编程)中的拦截器,或者为已有对象提供额外的功能。在Java中,我们可以使用Java.lang.reflect.Proxy类和java.lang.reflect....

    动态代理-jdk、cglib、javassist.zip

    Proxy类用于创建代理对象,而InvocationHandler接口则定义了代理对象的方法调用处理逻辑。当你需要为一个接口动态生成代理实现时,可以使用JDK动态代理。例如,你可能想为一组业务对象添加日志、事务控制等通用功能...

    动态代理与RMI远程调用

    3. 创建代理对象:使用`Proxy.newProxyInstance()`方法,传入类加载器、接口列表和自定义的`InvocationHandler`,返回代理对象。 接下来,我们转向RMI。RMI是一种Java提供的远程对象调用机制,它允许在不同的JVM...

    基于框架的Web开发-静态代理和动态代理原理.docx

    Java动态代理是面向切面编程(AOP)的一种实现方式,它允许我们在不修改原有代码的情况下,为已有的对象添加额外的功能。在Web开发中,动态代理常常用于增强业务逻辑,比如日志记录、权限检查等,使得代码更加模块化...

    java动态代理详细解析

    动态代理是指在程序运行时,根据指定的接口动态创建一个代理类,并且这个代理类可以实现与被代理对象相同的行为。在Java中,动态代理主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler...

    jdk与cglib动态代理与底层实现

    Proxy类用于创建代理对象,而InvocationHandler接口定义了调用处理程序,它处理代理对象的方法调用。当通过代理对象调用方法时,实际的操作是在InvocationHandler的`invoke()`方法中执行的。 2. **CGLIB动态代理**...

    动态代理及静态代理及ssh整合

    前者基于接口,后者则可以在没有接口的情况下通过字节码技术创建代理对象。Spring还提供了数据访问对象(DAO)的代理,可以自动处理如缓存、事务和异常转换等功能。 在实际项目中,当我们需要对服务进行扩展,如...

    设计模式之动态代理与spring的aop编程

    在学习和研究时,你可以打开这个文件,查看其中的Java代码,理解如何创建代理对象,以及如何实现InvocationHandler接口来定义代理逻辑。同时,你也可以寻找与Spring AOP相关的配置或示例,了解如何定义切面、通知和...

    基于Java动态代理和反射机制实现ORM

    动态代理是在运行时创建一个接口的实现类,这个实现类会调用我们指定的方法。Java中的`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口提供了实现动态代理的能力。反射则是Java提供的一种...

    cglib的动态代理需要的包

    这时,CGlib就派上用场了,它可以通过继承目标类来创建代理对象,即使目标类没有实现接口。 在使用CGlib时,我们需要引入CGlib的相关jar包,比如这里提到的`cglib-2.2.2.jar`。这个版本的CGlib包含了所有必要的类和...

    JAVA类加载机制与动态代理

    动态代理是一种在运行时创建代理类的技术。代理类是在程序运行时动态生成的,其字节码来源于以下几个途径: - **字节码操作库**:例如使用CGLIB、ASM等库自动生成代理类的字节码。 - **动态语言支持**:例如使用`...

    使用动态代理面向切面编程(AOP)

    - Spring框架提供了强大的AOP支持,它可以使用动态代理或者CGLIB(一种字节码生成库)来创建代理。当目标对象实现了至少一个接口时,Spring会使用JDK的动态代理;否则,它会转向CGLIB。 6. **Spring AOP的切面** ...

    jdk动态代理课程代码.rar

    这种方式虽然灵活,但当需要为多个接口或大量类创建代理时,代码会变得冗长且难以维护。 相比之下,JDK动态代理则在运行时根据给定的接口动态地生成代理类。我们只需要提供一个InvocationHandler接口的实现,这个...

Global site tag (gtag.js) - Google Analytics