码迷,mamicode.com
首页 > 其他好文 > 详细

常用设计模式之代理(动态代理)

时间:2016-11-17 01:15:28      阅读:145      评论:0      收藏:0      [点我收藏+]

标签:proxy   after   png   --   style   res   his   this   动态   

常用设计模式之代理(动态代理)

  • UML

技术分享

  • Code1

 1 interface Subject{void doSth();}
 2 class RealSubject implements Subject{
 3     public void doSth(){
 4         System.out.println("RealSubject doSth....");
 5     }
 6 }
 7 class ProxyHandler implements InvocationHandler
 8 {
 9     private Object obj;
10     public ProxyHandler(Object obj){ this.obj = obj; }
11     //private Subject subject;
12     //public ProxyHandler(Subject subject){this.subject = subject;}
13     public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException
14     {
15         System.out.println(proxy.getClass().getName());
16         System.out.println("before -----------");
17         Object result = method.invoke(this.obj, args);
18         System.out.println("after -----------");
19         return result;
20     }
21 }
22 public class Test{
23     public static void main(String[] args){
24         Subject proxy = (Subject)Proxy.newProxyInstance(
25                 Subject.class.getClassLoader(),
26                 new Class[]{ Subject.class },
27                 new ProxyHandler(new RealSubject()));
28         proxy.doSth();
29         System.out.println(proxy.getClass().getName());
30     }
31 }
32 /*out:
33 com.wrb.$Proxy0
34 before -----------
35 RealSubject doSth....
36 after -----------
37 com.wrb.$Proxy0
38 */
  • Code2

 1 interface UserService {
 2     void add();
 3 }
 4 class UserServiceImpl implements UserService {
 5     public void add() {
 6         System.out.println("add");
 7     }
 8 }
 9 /**
10  * 实现自己的InvocationHandler
11  */
12 class MyInvocationHandler implements InvocationHandler {
13 
14     // 目标对象
15     private Object target;
16 
17     /**
18      * 构造方法
19      * @param target 目标对象
20      */
21     public MyInvocationHandler(Object target) {
22         super();
23         this.target = target;
24     }
25 
26     /**
27      * 执行目标对象的方法
28      */
29     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
30         System.out.println("before------------------");
31 
32         Object result = method.invoke(target, args);
33 
34         System.out.println("after------------------");
35         return result;
36     }
37 
38     /**
39      * 获取目标对象的代理对象
40      * @return代理对象
41      */
42     public Object getProxy() {
43         return Proxy.newProxyInstance(
44                 Thread.currentThread().getContextClassLoader(),
45                 target.getClass().getInterfaces(),
46                 this);
47     }
48 }
49 public class Test{
50     public static void main(String[] args){
51         MyInvocationHandler handler = 
52                             new MyInvocationHandler(new UserServiceImpl());
53         UserService proxy = (UserService) handler.getProxy();
54         proxy.add();
55     }
56 }
57 /*out:
58 before------------------
59 add
60 after------------------
61 */
  • 实现原理

Proxy.newProxyInstance() 返回的代理对象subjectProxy(全都继承了父类Proxy)实现了其第二个参数中的全部接口,且包含了其第三个参数中的处理器对象handler。无论调用subjectProxy的哪个方法,实际都被转为调用处理器对象的invoke()方法。

class SubjectProxy extends Proxy implements Asubject, Bsubject, Csubject{

    private InvocationHandler myHandler;

    public  **( * ) {

       subjectProxy.myHandler.invoke(this, method, args);

    }

}

因为subjectProxy已经继承了父类Proxy,加上java单继承,因此此法只能实现接口的动态代理,无法实现类的动态代理。想实现类的动态代理,可以使用CGLIB(Code Generation Library)。(目前为止已接触三种代理的实现:装饰者模式实现的代理(decorator),JDK 动态代理(dynamic proxy) 和 Cglib 动态代理 (cglib proxy))。

参考:

JDK1.8 源码,

http://blog.csdn.net/jiankunking/article/details/52143504

http://rejoy.iteye.com/blog/1627405

http://www.360doc.com/content/14/0801/14/1073512_398598312.shtml

 

常用设计模式之代理(动态代理)

标签:proxy   after   png   --   style   res   his   this   动态   

原文地址:http://www.cnblogs.com/renbiao/p/6072062.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!