zoukankan      html  css  js  c++  java
  • 静态代理和动态代理

    设计模式中的代理模式理解。代理模式又分为动态代理和静态代理。今天就来入门一下 这两种代理的区别。

    首先 来说说 为什么要用代理模式呢。在我们日常程序开发中 经常会遇到这样的需求,要求改变某一个执行方法的逻辑,实际情况中  经常见到的 比如  在执行某个方法的时候  先来 查看执行此方法的权限。

    通常的方法  一开始 我们也许会直接改变方法体  在里面进行硬代码植入,这样就改变了原来的实现代码,如果此方法在程序种用到很多 势必造成大量的修改,也会改变 原有的测试准确性。在加上设计模式的OCP(开闭原则)  这也是不可行的。

    public interface UserManager {  
          
        /**  
         * 添加  
         */  
        public void add();  
          
        /**  
         * 查询  
         * @return  
         */  
        public int selectById();  
      
        /**  
         * 删除  
         */  
        public void del();  
          
    } 
    public class UserManagerIml implements UserManager {  
      
        @Override  
        public void add() {  
            // TODO Auto-generated method stub  
            System.out.println("添加");  
      
        }  
      
        @Override  
        public int selectById() {  
            // TODO Auto-generated method stub  
            System.out.println("查询");  
            return 2;  
        }  
      
        @Override  
        public void del() {  
            // TODO Auto-generated method stub  
            System.out.println("删除");  
      
        }  

    以上是接口和实现类的代码。

    突然老板 哪天说  我要在这些方法执行前 加一些特殊的处理,以checkMethod()  方法为例

    public void checkMethod(){
            System.out.println("--------security----------");
        }

    难道我们要在每个方法调用前都要加上此方法吗,那是一个什么样的工作量呢?就算加上了,后期老板又说 不需要呢? 我们继续注释掉? 这个时候  就出现了我们常说的代理模式,首先来看静态代理的处理方法。

    依然创建一个类  来实现 UserManager 接口。

    public class StaticProxyTest implements UserManager {
        
        private UserManager um;
        
        public StaticProxyTest(UserManager um){
            
            this.um = um;
        }
    
        @Override
        public void add() {
            
            checkMethod();
            um.add();
            
        }
    
        @Override
        public int selectById() {
            
            checkMethod();
            return um.selectById();
        }
    
        @Override
        public void del() {
    
            checkMethod();
            um.del();
        }
        
        //切点
        public void checkMethod(){
            System.out.println("--------security----------");
        }
        
    
    }

     实现代理功能的类,实现的方法也只是代理功能,并非真正的调用 最终实现方法。虽然此方法避免了  在程序各个地方 进行粘贴checkMethod方法,但是在 这个代理类中 还是重复了粘贴,并且此代理类 只代理了UserManager 一个类。拓展性 依然有局限。

    动态代理:

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class SecurityHandler implements InvocationHandler {
        
        private Object targetObject;
        
        //创建代理
        public Object createProxyObject(Object object){
        
             this.targetObject = object;
            
            return Proxy.newProxyInstance(object.getClass().getClassLoader(),
                                    object.getClass().getInterfaces(), this);
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // TODO Auto-generated method stub
            
            //切点
            checkMethod();
            
            return method.invoke(targetObject, args);
            
        }
    
        
        public void checkMethod(){
            System.out.println("--------security----------");
        }
    }

    动态代理  运用了几个 java jdk中常用的一些基础知识。在实现createProxyObject创建代理方法的时候 我们要实现一个代理Proxy.newProxyInstance创建代理,传入要代理类对象的装载器,接口方法,以及实现InvocationHandler接口的方法类,并返回代理类。代理类创建成功时  在执行中运用反射 Method调用 invoke()方法  传递参数。

    public class Client {
        
        public static void main(String[] args) {
            SecurityHandler sh = new SecurityHandler();
            UserManager um =  (UserManager)sh.createProxyObject(new UserManagerIml());
            um.add();
        }
    
    }

    执行打印:

    --------security----------

    添加

    在以前常用的 一些 系统中  一些权限的处理和实现 就是动态代理实现。还有spring 最重要的特性aop也是动态代理原理。

  • 相关阅读:
    动态规划-神奇的口袋V1
    独立项目-建立Web服务器-00
    连接数据库时出现:SQL Server 建立连接时出现与网络相关的或特定于实例的错误
    独立项目-MemoryStream-内存数据读写-01
    独立项目-场景刷怪、小怪AI、主角战斗、小怪死亡-01
    独立项目-角色控制器FSM-FSM有限状态机-03
    独立项目-角色控制器FSM-AnimatorController学习-02
    独立项目-角色控制器FSM-学习内容-01
    Unity中的UGUI之Rect Transform__02
    矩阵的平移、旋转与缩放
  • 原文地址:https://www.cnblogs.com/yanxioayu/p/6592991.html
Copyright © 2011-2022 走看看