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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 文江江 中级黑马   /  2014-3-18 11:27  /  981 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 文江江 于 2014-3-18 15:05 编辑

动态代理和代理的区别?如何创建动态代理?(简要明了哦,有demo有注释哦。。)谢谢了哦。。。

2 个回复

倒序浏览
首先来说静态代理:静态代理,是要为每一个需要代理的类生成一个对象,假如有一万个类,那么就要写1万个代理,这是非常恐怖的。下面是静态代理的实现;
代理和目标都要实现相同的接口:
  1. /**
  2. * 代理和目标类都要实现的接口
  3. * @author real
  4. *
  5. */
  6. public interface PersonInterface {

  7.         void getName();
  8. }
复制代码

目标类:
  1. /**
  2. * 需要被代理的类,目标类
  3. * @author real
  4. *
  5. */
  6. public class Person implements PersonInterface{

  7.         @Override
  8.         public void getName() {
  9.                 System.out.println("Person getName 执行");        
  10.         }
  11. }
复制代码
代理类:
  1. public class PersonProxy implements PersonInterface{

  2.         private PersonInterface person;
  3.         
  4.         public PersonProxy(PersonInterface person) {
  5.                 this.person = person;
  6.         }
  7.         
  8.         @Override
  9.         public void getName() {
  10.                 //在执行目标的真实方法之前,可以做其他事情,例如记录日志等。
  11.                 System.out.println("PersonProxy 的getName方法执行");
  12.                 //执行真实的目标类方法
  13.                 person.getName();
  14.         }

  15. }
复制代码
测试类:
  1. public class PersonTest {
  2.         
  3.         public static void main(String[] args) {
  4.                 //真实的Person
  5.                 PersonInterface person = new Person();
  6.                 //Person的代理,需要把Person穿进去
  7.                 PersonInterface personProxy = new PersonProxy(person);
  8.                
  9.                 //直接调用person的方法
  10.                 person.getName();
  11.                 //通过代理调用person的方法
  12.                 personProxy.getName();

  13.         }
  14. }
复制代码
以上代码就是实现静态代理的方法,上面的问题就是如果需要代理的类太多,就得用到了动态代理。在jdk中可以动态的生成代理类。
下面是一个动态代理类:

  1. public class Proxy1 {

  2.         private Object target;
  3.         
  4.         //将需要被代理的类通过对象传入进来
  5.         public Proxy1(Object target) {
  6.                 this.target = target;
  7.         }
  8.         
  9.         /**
  10.          * 通过jdk的Proxy动态的生成target的代理类。
  11.          * @return
  12.          */
  13.         public Object getProxy() {
  14.                
  15.                 /**
  16.                  * Proxy.newProxyInstance()方法需要的三个参数分别问,这个代理类的ClassLoader,
  17.                  * 这个类所有实现的接口,还有一个InvocationHandler,所有的代理方法都要通过里面的invoke方法,
  18.                  * 然后我们可以在invoke方法内部调用target的真实方法,还可以执行其他代码
  19.                  */
  20.                 return Proxy.newProxyInstance(target.getClass().getClassLoader(),
  21.                                 target.getClass().getInterfaces(),
  22.                                 new InvocationHandler() {                        
  23.                         
  24.                                         @Override
  25.                                         public Object invoke(Object proxy, Method method, Object[] args)
  26.                                                         throws Throwable {
  27.                                                 //retVal就是目标对象方法执行后的返回值
  28.                                                 System.out.println("动态代理类。记录日志");
  29.                                                 Object retVal = method.invoke(target, args);
  30.                                                 return retVal;
  31.                                         }
  32.                                 });               
  33.         }
  34. }
复制代码

测试代理类:
  1.                 Proxy1 p1 = new Proxy1(person);
  2.                 PersonInterface personProxy1 = (PersonInterface) p1.getProxy();
  3.                 personProxy1.getName();
复制代码

有了动态代理,就可以代理任何你传入的对象了。不会像静态代理一样限制类型了。



评分

参与人数 1技术分 +1 收起 理由
菜小徐 + 1

查看全部评分

回复 使用道具 举报
房建斌 发表于 2014-3-18 13:08
首先来说静态代理:静态代理,是要为每一个需要代理的类生成一个对象,假如有一万个类,那么就要写1万个代 ...

谢谢啊,很简洁,好!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马