首页 > Java开发 > 动态代理模式

动态代理模式

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

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

动态代理

 

    接口UserManager

[java] view plaincopyprint?

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

    实现类UserManagerImpl

[java] view plaincopyprint?

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

    代理类LogHandler

 

 

[java] view plaincopyprint?

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

 

    客户端Client

 

[java] view plaincopyprint?

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

 

    运行结果

    

    时序图

    

总结

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

本文固定链接: http://www.devba.com/index.php/archives/986.html | 开发吧

报歉!评论已关闭.