代理模式(Proxy)

代理模式是对象的结构型模式,代理模式给某一个对象提供了一个代理对象,并由代理对象控制对原对象的引用。

代理分静态代理和动态代理

一、静态代理

代码示例

接口

[java] view plain copy
 
 print?
  1. package com.jialinl;  
  2.   
  3. public interface InterfaceUserManage {  
  4.     public void AddUser();  
  5.     public void DelUser();  
  6.     public void ModifyUser();  
  7. }  


目标类

[java] view plain copy
 
 print?
  1. package com.jialinl;  
  2.   
  3. public class UserManageImp implements InterfaceUserManage {  
  4.   
  5.     @Override  
  6.     public void AddUser() {  
  7.         System.out.println("UserManageImp>>>>>AddUser");  
  8.     }  
  9.   
  10.     @Override  
  11.     public void DelUser() {  
  12.         System.out.println("UserManageImp>>>>>DelUser");  
  13.     }  
  14.   
  15.     @Override  
  16.     public void ModifyUser() {  
  17.         System.out.println("UserManageImp>>>>>ModifyUser");  
  18.     }  
  19.   
  20. }  


代理类

[java] view plain copy
 
 print?
  1. package com.jialinl;  
  2.   
  3. public class UserManageImpProxy implements InterfaceUserManage {  
  4.   
  5.     private InterfaceUserManage userManage;  
  6.       
  7.     public UserManageImpProxy(InterfaceUserManage userManage) {  
  8.         this.userManage = userManage;  
  9.     }  
  10.       
  11.     @Override  
  12.     public void AddUser() {  
  13.         try {  
  14.             //记录日志等操作,完全可以使用代理来完成  
  15.             System.out.println("start-->>addUser()");  
  16.             userManage.AddUser();  
  17.             System.out.println("success-->>addUser()");  
  18.         }catch(Exception e) {  
  19.             e.printStackTrace();  
  20.             System.out.println("error-->>addUser()");  
  21.         }     
  22.     }  
  23.   
  24.     @Override  
  25.     public void DelUser() {  
  26.         //代理操作。。。。。  
  27.         userManage.DelUser();  
  28.     }  
  29.   
  30.     @Override  
  31.     public void ModifyUser() {  
  32.         //代理操作。。。。。  
  33.         userManage.ModifyUser();  
  34.     }  
  35.   
  36. }  


客户端调用

[java] view plain copy
 
 print?
  1. package com.jialinl;  
  2.   
  3. public class Client {  
  4.     public static void main(String[] args)  
  5.     {  
  6.         InterfaceUserManage userManager = new UserManageImpProxy(new UserManageImp());  
  7.         userManager.AddUser();  
  8.     }  
  9. }  

输出结果

start-->>addUser()
UserManageImp>>>>>AddUser
success-->>addUser()


从UML图和代码分析可以看出,静态代理会建立大量的类,一个接口基本对应一个代理类,而且(代理操作)重复的代码在每个方法中都有出现,我们应该杜绝这种重复。下面就要看我们的动态代理。

二、动态代理

JDK动态代理能对实现了接口的类进行代理,采用JDK动态代理必须实现InvocationHandler接口,采用Proxy类创建相应的代理类。

代码示例:

接口

[java] view plain copy
 
 print?
  1. package com.jialin;  
  2.   
  3. public interface InterfaceUserManage {  
  4.     public void AddUser(String userName,String userAge);  
  5.     public void DelUser();  
  6.     public void ModifyUser();  
  7. }  


目标类

[java] view plain copy
 
 print?
  1. package com.jialin;  
  2.   
  3. public class UserManageImp implements InterfaceUserManage {  
  4.   
  5.     @Override  
  6.     public void AddUser(String userName,String userAge) {  
  7.         System.out.println("UserManageImp>>>>>AddUser("+userName+","+userAge+")");  
  8.     }  
  9.   
  10.     @Override  
  11.     public void DelUser() {  
  12.         System.out.println("UserManageImp>>>>>DelUser");  
  13.     }  
  14.   
  15.     @Override  
  16.     public void ModifyUser() {  
  17.         System.out.println("UserManageImp>>>>>ModifyUser");  
  18.     }  
  19.   
  20. }  


代理

[java] view plain copy
 
 print?
  1. package com.jialin;  
  2.   
  3. import java.lang.reflect.InvocationHandler;  
  4. import java.lang.reflect.Method;  
  5. import java.lang.reflect.Proxy;  
  6.   
  7. public class PublicProxy implements InvocationHandler {  
  8.   
  9.     private Object targetObject;  
  10.       
  11.     public Object newProxyInstance(Object targetObject) {  
  12.         this.targetObject = targetObject;  
  13.         return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),  
  14.                                targetObject.getClass().getInterfaces(), this);  
  15.     }  
  16.       
  17.     public Object invoke(Object proxy, Method method, Object[] args)  
  18.             throws Throwable {  
  19.         System.out.println("开始调用目标方法-->>" + method.getName());  
  20.         for (int i=0; i<args.length; i++) {  
  21.             //打印调用目标方法的参数  
  22.             System.out.println(args[i]);  
  23.         }  
  24.           
  25.         try {  
  26.             //调用目标方法  
  27.             method.invoke(targetObject, args);  
  28.             System.out.println("调用-->>" + method.getName()+"--成功");   
  29.         }catch(Exception e) {  
  30.             e.printStackTrace();  
  31.             System.out.println("调用-->>" + method.getName()+"--失败");  
  32.             throw e;  
  33.         }  
  34.         return null;  
  35.     }  
  36.   
  37. }  


客户端

[java] view plain copy
 
 print?
  1. package com.jialin;  
  2.   
  3. public class Client {  
  4.     public static void main(String[] args)  
  5.     {  
  6.         PublicProxy publicProxy = new PublicProxy();  
  7.         InterfaceUserManage userManager = (InterfaceUserManage)publicProxy.newProxyInstance(new UserManageImp());  
  8.         userManager.AddUser("王五","17");  
  9.     }  
  10. }  


输出结果:

开始调用目标方法-->>AddUser
王五
17
UserManageImp>>>>>AddUser(王五,17)
调用-->>AddUser--成功

原文地址:https://www.cnblogs.com/csguo/p/7569827.html