zoukankan      html  css  js  c++  java
  • 代理模式(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--成功

  • 相关阅读:
    把Chrome浏览器变成文本编辑器
    pigcms 标签读不出
    全排列函数
    线性基(二
    线性基(一
    fabs() abs()
    字面量声明的函数,后边最好加一个分号,否则的话,在控制台执行有问题的
    mongo集群
    linux的查找命令
    mysql 解决Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’错误
  • 原文地址:https://www.cnblogs.com/csguo/p/7569827.html
Copyright © 2011-2022 走看看