首页 > 代码库 > 代理设计模式

代理设计模式

案例需求:需要在原来的dao实现类的方法中,加入日志的记录功能,对原有的功能进行增强

1. 静态代理

静态代理的组成:

抽象接口:目标类和代理类必须实现同一个抽象接口。

目标类:封装了原始的核心功能

代理类:拥有目标对象的引用,同时完成扩展功能的实现

总结:将核心功能和扩展功能在代码的实现上,进行了分离在使用的时候将分离实现的功能进行合并。

应用场景:对系统中原有的功能进行升级(可以不修改源码 )

系统中如果分散着一些共性的,公共功能的代码(将这样功能的代码抽取进行单独的开发)

     

2. 动态代理

动态代理的实现原理:

动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。

2.1动态代理实现的API

Proxy 提供用于创建动态代理类和实例的静态方法

static Object      newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 

返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序

InvocationHandler 是代理实例的调用处理程序 实现的接口

当使用代理类的对象调用某个方法的时候 ,该方法的执行会被InvocationHandler对象拦截

 Object     invoke(Object proxy, Method method, Object[] args) 

在代理实例上处理方法调用并返回结果。

2.2 创建Dao接口

1 public interface Dao
2 {
3     public String save(String uname);
4     public String delete(Integer id);
5 }

2.3 创建实现类

 1 public class DaoImpl implements Dao
 2 {
 3     @Override
 4     public String save(String uname)
 5     {
 6         /**
 7          * code....
 8          * **/
 9         System.out.println("----------数据保存到数据库---------");
10         return "hello  " + uname;
11     }
12 
13     @Override
14     public String delete(Integer id)
15     {
16         // TODO Auto-generated method stub
17         System.out.println("----------数据库删除操作------------");
18         return "id=" + id;
19     }
20 }

2.4创建工具类

产生代理对象

 1 public class GetProxyInstance
 2 {
 3     private Object target; // 目标对象
 4 
 5     public GetProxyInstance()
 6     {
 7     }
 8 
 9     public GetProxyInstance(Object target)
10     {
11         this.target = target;
12     }
13 
14     public Object getProxyInstance()
15     {
16         System.out.println("----------getProxyInstance");
17         return Proxy.newProxyInstance(GetProxyInstance.class.getClassLoader(),// 类加载器对象
18                 new Class[]
19                 { Dao.class },// 代理对象需要实现的接口
20                 new MyInvocationHandler());// 代理对象调用的方法对应的处理器
21     }
22 
23     // 代理对象调用的方法对应的处理器类
24     class MyInvocationHandler implements InvocationHandler
25     {
26         @Override
27         public Object invoke(Object proxy, // 代理对象
28                 Method method, // 被拦截到的方法
29                 Object[] args) // 拦截的方法执行需要的参数
30                 throws Throwable
31         {
32             // TODO Auto-generated method stub
33             String methodName = method.getName();// 获得方法的名称
34             // System.out.println(methodName+"--------"+Arrays.toString(args));
35             if (methodName.equals("save"))
36             {
37                 System.out.println("-------完成日志的记录----------" + new Date()
38                         + "----" + Arrays.toString(args));
39             }
40             // 通过反射完成方法的调用:完成目标对象方法的调用,放行
41             Object rv = method.invoke(target, args);
42             //
43             return rv;
44         }
45     }
46 }

2.5 创建测试类

 1 public class TestProxy
 2 {
 3     public static void main(String[] args)
 4     {
 5         // 创建GetProxyInstance对象,传入被代理的目标对象
 6         GetProxyInstance gpi = new GetProxyInstance(new DaoImpl());
 7         // 获得代理对象
 8         Object obj = gpi.getProxyInstance();
 9         // System.out.println(obj instanceof Dao);
10         // 向下转型
11         Dao dao = (Dao) obj;
12         String result = dao.save("乌龟");
13         String result2 = dao.delete(100);
14         // System.out.println("======"+result);
15         System.out.println(dao.getClass());
16         new DaoImpl().save("王八");
17     }
18 }

 

代理设计模式