zoukankan      html  css  js  c++  java
  • 设计模式之JDK动态代理

    1.代理模式

      以租房为例子,你是一位出租用户,有的租客不会直接和你谈,而是去找中介谈。

      租客(调用者)--->中介(代理对象)--->出租用户(真实对象,被代理)

    2.什么是静态代理

      由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。

    代码:

     被代理类 

    package com.bl.test3;
    
    public interface Person {
        void eat();
    }
    package com.bl.test3;
    
    public class Student implements Person {
        private String name;
        public Student(String name){
            this.name=name;
        }
        
        @Override
        public void eat() {
            System.out.println(name+"在吃饭");
        }
    
    }

    代理类

    package com.bl.test3;
    
    public class PersonProxy implements Person{
        //被代理的学生
        Student stu;
        public PersonProxy(Person p){
            //只代理学生
            if(p.getClass()==Student.class){
                stu=(Student)p;
            }
        }
        
        public void eat(){
            System.out.println("操作前");
            stu.eat();
            System.out.println("操作后");
        }
    }

    测试

    package com.bl.test3;
    
    public class Test {
        public static void main(String[] args) {
            //被代理对象
            Person p=new Student("小明");
            //生成代理对象
            Person person = new PersonProxy(p);
            person.eat();
        }
    }

    打印结果

      

    操作前
    小明在吃饭
    操作后

    3.什么是动态代理

       在程序运行时,运用反射机制动态创建而成。

    代码(JDK动态代理)

    实现:一个是 InvocationHandler(Interface)、另一个则是 Proxy(Class)

    被代理类 

    package com.bl.test2;
    
    public interface House {
        public void type();
        public void shape(String shape);
    }
    package com.bl.test2;
    
    public class Villa implements House {
    
        @Override
        public void shape(String shape) {
            System.out.println("我的形状是"+shape);
        }
    
        @Override
        public void type() {
            System.out.println("我的类型是别墅");
        }
    
    
    }

    代理类:

    package com.bl.test2;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    //代理对象
    public class HouseProxy implements InvocationHandler {
     //被代理对象 
    private Object house; public HouseProxy(Object stuObject){ this.house=stuObject; } //proxy:被代理对象 //method: 当前调用的方法 //args: 方法参数 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("--------操作前--------"); method.invoke(house, args); System.out.println("--------操作后--------"); return null; } }

    测试类:

    package com.bl.test2;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Proxy;
    
    public class Test {
        public static void main(String[] args) {
            House student=new Villa();
            InvocationHandler handler=new HouseProxy(student);
            //Proxy.newProxyInstance(loader, interfaces, h)
            /*
                ClassLoader loader,:指定当前目标对象使用类加载器,获取加载器的方法是固定的
                Class<?>[] interfaces,:目标对象实现的接口的类型,使用泛型方式确认类型
                InvocationHandler h:事件处理,执行目标对象的方法时,会触发事件处理器的方法,会把当前执行目标对
             */
            //现在的House是一个代理对象,现在访问方法会进入到,代理的逻辑方法invoke里
            House s=(House) Proxy.newProxyInstance(handler.getClass().getClassLoader(), student.getClass().getInterfaces(), handler);
            System.out.println(s.getClass().getName());
            s.shape("很大");
            s.type();
            }
    }

    打印结果:

    $Proxy0
    --------操作前--------
    我的形状是很大
    --------操作后--------
    --------操作前--------
    我的类型是别墅
    --------操作后--------

    应用:Spring AOP机制,RPC框架

    作用:主要用来做方法的增强,让你可以在不修改源码的情况下,增强一些方法,在方法执行前后做任何你想做的事情(甚至根本不去执行这个方法)

    如果有错误希望大家指出来,谢谢。

      

  • 相关阅读:
    软件编程思想读后感
    上交所历史数据分析系统项目总结
    2013学习总结----JavaScript
    快来领取你专属的css背景图案
    小朋友,听说你还不会css中的条纹背景?
    特殊要求下的背景定位的解决方案
    css中多边框实现的方式
    一个按钮样式测试出你的 css功力
    一次优雅的表单验证设计
    使用JavaScript浅谈组合模式
  • 原文地址:https://www.cnblogs.com/tysl/p/10854165.html
Copyright © 2011-2022 走看看