设计模式之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框架

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

 

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

 

  

posted @ 2019-05-12 22:56  入门小伙陶先生  阅读(216)  评论(0编辑  收藏  举报