A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 刘士林 中级黑马   /  2012-11-3 21:58  /  1271 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

动态代理到底是什么,看了视频也没看出来代理类到底有什么功用啊,
代理类怎么就把目标类给代理了,没弄明白!
谁能给简单地解释一下?谢谢啦!

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1

查看全部评分

2 个回复

倒序浏览
代理模式
  代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
  代理模式一般涉及到的角色有:
  抽象角色:声明真实对象和代理对象的共同接口;
  代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
  真实角色:代理角色所代表的真实对象,是我们最终要引用的对象

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1

查看全部评分

回复 使用道具 举报
代理模式是Java 设计模式中很常用的一种设计模式,它的特点是代理类和被代理类具有相同的接口,这样代理类才能代理被代理类。当我们执行被代理类的某些方法的时候,委托给代理类,代理类可以在被代理类方法的执行前后多做一些事情。类似于Spring中的AOP
代理类可分为两种形似。一种为静态代理类,由程序开发人员自己编写代理类;另外一种为动态代理类,在程序运行时,运用反射机制动态生成。动态代理类不需要程序开发人员编写源代码。运用Java的反射机制生成,扩展容易。

java.lang.reflect 包中的Proxy类和InvocationHandler接口提供了生成动态代理类的功能。
Proxy类通过静态方法创建代理类和代理类的实例
下面通过一个简单的实例讲解如何使用动态代理
首先创建一个简单的接口IHello,其中只有一个方法sayHello,无论是常规类,还是代理类都需要实现此接口。
  1. <font color="black">package dynamicpro;
  2. public interface IHello {
  3.     public void sayHello();
  4. }</font>
复制代码
创建实现此接口的类HelloImpl,此类为日后的被代理类
  1. <font color="black">package dynamicpro;
  2. public class HelloImpl implements IHello {
  3.     public HelloImpl() {
  4.     }

  5.     public void sayHello() {
  6.         System.out.println("Hello World");
  7.     }

  8. }</font>
复制代码
下面通过工厂方法创建动态代理类及其实例
  1. <font color="black">package dynamicpro;
  2. import java.lang.reflect.*;
  3. public class HelloFactory {
  4.     public HelloFactory() {
  5.     }
  6.     public static IHello getHelloProxy(final IHello hello){
  7.         InvocationHandler handler=new InvocationHandler(){
  8.             public Object invoke(Object proxy, Method method, Object[] args) throws
  9.                     Throwable {
  10.                 System.out.println("before calling "+method);
  11.                 Object result=method.invoke(hello,args);
  12.                 System.out.println("after calling "+method);
  13.                 return result;
  14.             }
  15.         };
  16.         Class classType=IHello.class;
  17.         return (IHello)Proxy.newProxyInstance(classType.getClassLoader(),new Class[]{classType},handler);
  18.     }
  19. }</font>
复制代码


创建动态代理类时,使用Proxy.newProxyInstance方法。此方法需要InvocationHandler接口类型的参数。所以创建InvocationHandler对象,并实现invoke方法。当动态代理类代理其他的类的时候,调用此方法。invoke方法的三个参数分别为:代理类对象,调用的被代理类的方法,方法的参数。我们可以在invoke方法中编写适当的代码,当执行被代理类的方法的时候多做置前和置后的一些处理。比如这里只是在方法的执行前后输出一些内容。

Proxy.newProxyInstance方法返回动态代理类的实例,第一个参数指名被代理类的类型,显然是IHello接口类型,第二个参数是被代理类所实现的所有的接口类型。显然也是IHello.class。第三个参数即为刚才创建的InvocationHandler对象,当执行被代理类的方法时候,调用其中的invoke方法。

编写测试类进行测试:
  1. <font color="black">package dynamicpro;
  2. public class HelloTest {
  3.     public HelloTest() {
  4.     }

  5.     public static void main(String[] args) {
  6.         IHello hello=new HelloImpl();
  7.         IHello helloProxy=HelloFactory.getHelloProxy(hello);
  8.         helloProxy.sayHello();
  9.     }
  10. }</font>
复制代码
运行结果如下:
  1. <font color="black">before calling public abstract void
  2. dynamicpro.IHello.sayHello()
  3. Hello World
  4. after calling public abstract
  5. void dynamicpro.IHello.sayHello()</font>
复制代码

评分

参与人数 1技术分 +2 收起 理由
滔哥 + 2

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马