动态代理模式

 这篇博客对应上篇博客《静态代理模式》,我们来说一下动态代理,静态代理之所以扩展和维护比较困难,是因为代码写的太死,没有可替换的余地;针对代码写得死能想到什么解决办法?对,就是反射。

    使用反射可以很到的解决决定加载哪个代理类的问题,避免了每个代理类都要重复写的问题,话不多说,来看代码。

动态代理

    接口UserManager

[java]  view plain copy print ?
  1. /*** 
  2.  * 用户控制接口 
  3.  * @author Administrator 
  4.  * 
  5.  */  
  6. public interface UserManager {  
  7.   
  8.     public void addUser(String userId,String userName);  
  9.     public void modifyUser(String userId,String userName);  
  10.     public void delUser(String userId);  
  11.     public String findUser(String userId);  
  12. }  

    实现类UserManagerImpl

[java]  view plain copy print ?
  1. /**** 
  2.  * 用户管理真正的实现类 
  3.  * @author Administrator 
  4.  * 
  5.  */  
  6. public class UserManagerImpl implements UserManager {  
  7.   
  8.     /***** 
  9.      * 添加用户 
  10.      */  
  11.     public void addUser(String userId, String userName) {  
  12.             System.out.println("正在添加用户,用户为:"+userId+userName+"……");  
  13.     }  
  14.     /***** 
  15.      * 删除用户 
  16.      */  
  17.     public void delUser(String userId) {  
  18.         System.out.println("delUser,userId="+userId);  
  19.     }  
  20.     /*** 
  21.      * 查找用户 
  22.      */  
  23.     public String findUser(String userId) {  
  24.         System.out.println("findUser,userId="+userId);  
  25.         return userId;  
  26.     }  
  27.   
  28.     public void modifyUser(String userId, String userName) {  
  29.         System.out.println("modifyUser,userId="+userId);  
  30.     }  
  31. }  

    代理类LogHandler

[java]  view plain copy print ?
  1. import java.lang.reflect.InvocationHandler;  
  2. import java.lang.reflect.Method;  
  3. import java.lang.reflect.Proxy;  
  4.   
  5. public class LogHandler implements InvocationHandler {  
  6.       
  7.     private Object targetObject;  
  8.       
  9.     public Object newProxyInstance(Object targetObject) {  
  10.         this.targetObject = targetObject;  
  11.         return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),  
  12.                                targetObject.getClass().getInterfaces(), this);  
  13.     }  
  14.       
  15.     public Object invoke(Object proxy, Method method, Object[] args)  
  16.             throws Throwable {  
  17.         Object ret = null;  
  18.               
  19.         try {  
  20.             System.out.println("正在进行操作前的准备工作……");  
  21.             //调用目标方法  
  22.             ret = method.invoke(targetObject, args);  
  23.             System.out.println("操作成功,正在进行确认处理……");  
  24.         } catch (Exception e) {  
  25.             e.printStackTrace();  
  26.             System.out.println("error-->>" + method.getName());  
  27.             throw e;  
  28.         }  
  29.         return ret;  
  30.     }  
  31. }  

    客户端Client

[java]  view plain copy print ?
  1. public class Client {  
  2.   
  3.     /** 
  4.      * @param args 
  5.      */  
  6.     public static void main(String[] args) {  
  7.         LogHandler logHandler = new LogHandler();  
  8.         UserManager userManager = (UserManager)logHandler.newProxyInstance(new UserManagerImpl());  
  9.         userManager.findUser("0001");  
  10.     }  
  11. }  

    运行结果

    

    时序图

    动态代理模式_第1张图片


总结

    动态代理模式通过使用反射,可以在运行期决定加载哪个类,避免了一个类对应一个代理的问题;同时,通过统一的invoke方法,统一了代理类对原函数的处理过程,使用动态代理很大程度上减少了重复的代码,降低了维护的复杂性和成本。

你可能感兴趣的:(动态代理模式)