初步了解JDK动态代理

Posted 清风拂来

tags:

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

代理模式基本概念:
1.代理模式的作用:为其他对象提供一种以控制对方的访问
在某种情况下,一个客户不想或者不能直接引用另一个对象,代理可以在客户端和目标对象之间起到中介的作用
代理的角色:
(1)抽象角色:声明真实对象和代理对象的共同接口
(2)代理角色:代理对象内部含有真实对象的引用,从而可以操纵真实的对象,同时代理对象提供与真实对象相同的接口,以便在任何时候都能代替真实对象。代理对象可以在执行真实对象操作时附加其他的操作,相对于真实对象进行封装。
(3)真实角色:代理对象所代理的真实角色,是我们要引用的对象

2.JDK动态代理
JDK动态代理可以为所有接口的实现类提供代理
动态代理开发步骤:
(1)创建一个实现接口InvocationHandler的类,它必须实现invoke方法
(2)创建被代理对象的类和接口
(3)通过Proxy.newProxyInstance()来创建代理类
(4)通过代理来调用被代理对象的方法

静态代理demo:模拟通过代理租房

技术分享图片
1 package proxydemo;
2 
3 public interface HireHouse {
4 
5     public void hire();
6 }
HireHouse
技术分享图片
 1 package proxydemo;
 2 
 3 public class HireHouseImpl implements HireHouse {
 4 
 5     @Override
 6     public void hire() {
 7         System.out.println("我要租房");
 8 
 9     }
10 
11 }
HireHouseImpl

代理类,实现HireHouse接口,持有代理对象(真实对象的引用)

技术分享图片
 1 package proxydemo;
 2 
 3 public class HireHouseProxy implements HireHouse {
 4 
 5     private HireHouse hh;//代理对象,持有真实对象的引用
 6     
 7     
 8     public HireHouseProxy(HireHouse hh) {
 9         /*多态方式,接收接口的实现类对象,为静态代理,缺点是,只能给租房这件事做代理,
10          *因为传递进来的是HireHouse这个接口的实现类对象 ,不能代理其他的事情*/
11         super();
12         this.hh = hh;
13     }
14 
15 
16     @Override
17     public void hire() {
18         System.out.println("收中介费");//代理做的事情
19         hh.hire();//真实对象租房
20         System.out.println("扣押金");//代理做的
21 
22     }
23 
24 }
HireHouseProxy

调用代理类:

技术分享图片
 1 package proxydemo;
 2 
 3 public class Client {
 4 
 5     public static void main(String[] args) {
 6         HireHouse proxyHire = new HireHouseProxy(new HireHouseImpl());
 7         System.out.print("---通过代理租房:");
 8         proxyHire.hire();//通过代理租房
 9         System.out.print("---真实对象自己租房:");
10         new HireHouseImpl().hire();//真实对象自己租房
11         
12     }
13 }
Client

 动态代理demo:

 1 package proxydemo.dynamic.proxy;
 2 /**
 3  * 真实对象和代理对象的共同接口,不仅仅能租房。
 4  * @author Administrator
 5  *
 6  */
 7 public interface HireHouse {
 8 
 9     public void hire();
10 }

接口实现类:

1 package proxydemo.dynamic.proxy;
2 
3 public class HireHouseImpl implements HireHouse {
4 
5     @Override
6     public void hire() {
7         System.out.println("我要租房");
8     }
9 }

代理类,实现InvocationHandler 接口

 1 package proxydemo.dynamic.proxy;
 2 
 3 import java.lang.reflect.InvocationHandler;
 4 import java.lang.reflect.Method;
 5 
 6 /**
 7  * 实现InvocationHandler接口,通过反射去调用被代理的接口
 8  * @author Administrator
 9  * 
10  */
11 public class HireProxy implements InvocationHandler {
12     // 被代理的真实角色
13     private Object obj;// 真实角色,要给任何对象做代理,只能是持有Object类型的对象
14     
15     public HireProxy(Object obj) {
16         super();
17         this.obj = obj;
18     }
19 
20 /**
21  * jdk动态代理,被代理对象必须实现接口
22  * 被代理的对象必然实现共同的Hire接口,那么就有方法
23  * method:被代理的对象的接口中的方法,要调用方法,必须有对象,此处这个对象就是被代理对象,因此必须要指定被代理的对象
24  * args是被代理对象接口的方法的参数,调用proxy对象的method方法
25  */
26     @Override
27     public Object invoke(Object proxy, Method method, Object[] args)
28             throws Throwable {
29         System.out.println("前置工作");
30 //        for (Object object : args) {
31 //            System.out.print("invoke方法中的第三个参数:"+object +" ");//给list做代理时测试用
32 //        }
33         Object invoke = method.invoke(obj, args);
34         System.out.println("\n后置工作");
35         return invoke;
36     }
37 
38 }

动态代理测试:

 1 package proxydemo.dynamic.proxy;
 2 
 3 import java.lang.reflect.Proxy;
 4 import java.util.ArrayList;
 5 import java.util.List;
 6 
 7 public class Client {
 8 
 9     public static void main(String[] args) {
10         // 创建被代理的接口实现类对象
11          HireHouseImpl hhi = new HireHouseImpl();
12          //创建代理对象:第一个参数是被代理的对象的类加载器,第二个是被代理对象的类的所有接口,第三个参数是自定义代理类的角色
13          HireHouse hh =
14          (HireHouse)Proxy.newProxyInstance(hhi.getClass().getClassLoader(),
15          hhi.getClass().getInterfaces(), new HireProxy(hhi));
16          hh.hire();
17 
18         // 给list做代理
19 //        List list = new ArrayList();
20 //        List hh1 = (List) Proxy.newProxyInstance(list.getClass()
21 //                .getClassLoader(), list.getClass().getInterfaces(),
22 //                new HireProxy(list));
23 //        hh1.add("张三");
24 //        hh1.get(0);//被代理对象的所有方法都被代理了
25 
26     }
27 }

 













以上是关于初步了解JDK动态代理的主要内容,如果未能解决你的问题,请参考以下文章

JDK动态代理

深入理解Spring AOP之二代理对象生成

jdk动态代理的简单了解

jdk动态代理的简单了解

动态代理之JDK Proxy浅析

简单jdk动态代理