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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了常用设计模式之代理(动态代理)相关的知识,希望对你有一定的参考价值。

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

  • 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

 

以上是关于常用设计模式之代理(动态代理)的主要内容,如果未能解决你的问题,请参考以下文章

Java动态代理之JDK实现和CGlib实现

Java设计模式-代理模式之动态代理(附源代码分析)

Java之动态代理简介

#yyds干货盘点# 设计模式之代理模式:动态代理

Spring之静态/动态代理模式

设计模式之动态代理