• java反射机制应用之动态代理


    1.静态代理类和动态代理类区别

    静态代理:要求被代理类和代理类同时实现相应的一套接口;通过代理类的对象调用重写接口的方法时,实际上执行的是被代理类的同样的

    方法的调用。

    动态代理在程序运行时,根据被代理类及其实现的接口,动态的创建一个代理类。当调用代理类的实现的抽象方法时,就发起对被代理类同样方法的调用。

    涉及到的技术点:

    ①提供一个实现了InvocationHandler接口实现类,并重写其invoke()方法

    ②Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),h);

    2.动态代理的优点

    它可以在程序运行时动态的为任何想要被代理的类生成代理对象(代理对象中包含了编写的通用代理逻辑),它不用去关心被代理的类到底是怎样的,可以与被代理的类完全脱离关系,从而灵活的运用到不同的应用场景中。

    下面通过具体的代码来体现动态代理的好处

    第一个是静态代理的代码

    package 反射机制;
    //静态代理特征是代理类和目标对象的类都是在编译期间确定下来的
    //不利于程序的扩展。同时,每一个代理类只能为一个接口服务,这样一来
    //程序开发必然产生过多的代理
    //接口
    interface ClothProduct{
    void productCloth();
    }

    //被代理类
    class NikeClothFactory implements ClothProduct{

    @Override
    public void productCloth() {
    System.out.println("nike生产一批衣服");

    }

    }
    //代理类
    class ProxyFactory implements ClothProduct{
    ClothProduct cf;
    //创建代理类的对象时,实际传入一个被代理类的对象
    public ProxyFactory(ClothProduct cf) {
    this.cf=cf;
    }
    @Override
    public void productCloth() {

    System.out.println("代理类开始执行");
    cf.productCloth();
    }

    }
    public class JingTaiDaiLi {
    public static void main(String[] args) {
    NikeClothFactory nc=new NikeClothFactory();
    ProxyFactory proxy=new ProxyFactory(nc);
    proxy.productCloth();
    }
    }
    //每建立一个被代理类就必须建立一个代理类,则多个被代理类就得写多个代理类太麻烦

    下面是动态代理类

    package 反射机制;

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;

    //动态代理是指客户通过代理类来调用其他对象的方法,
    //并且是在程序运行时根据需要动态创建目标类的代理对象

    interface Subject{
    void action();
    }

    //被代理类
    class RealSubject implements Subject{
    public void action()
    {
    System.out.println("我是被代理类");
    }
    }

    class MyIvocationHandler implements InvocationHandler{
    Object obj;//实现了接口的被代理类的对象的声明
    //给被代理类的对象实例化,返回一个代理类的对象
    public Object blind(Object obj) {
    this.obj=obj;

    return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this) ;
    }
    //当通过代理类的对象发起对重写的方法调用时都会转化为对如下的Invoke方法的调用
    @Override
    public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
    Object obj1=arg1.invoke(obj, arg2);

    return obj1;
    }
    }
    public class DongTaiDaiLi {
    public static void main(String[] args) {
    //被代理类的对象
    RealSubject rs=new RealSubject();
    //2创建一个实现实现IvocationHandler接口的类的对象
    MyIvocationHandler mh=new MyIvocationHandler();
    //3调用blind()方法,动态的返回一个同样实现real所在类的接口subject的代理类的对象
    Object obj=mh.blind(rs);
    Subject sub=(Subject)obj;//此时sub就是代理类对象
    sub.action();//转到IvocationHandler接口的实现类的invoke()方法的调用
    System.out.println();
    //利用静态代理的被代理类体现动态代理
    NikeClothFactory Nick=new NikeClothFactory();
    //ClothProduct cp=new ClothProduct();
    ClothProduct cp=(ClothProduct)mh.blind(Nick);
    cp.productCloth();
    }
    }

    所有被代理类都对应一个代理类,当通过代理类的对象发起对重写的方法调用时都会转化为对唯一一个代理类的Invoke方法的调用,不同的被代理类对应不同的method,所以invoke方法是动态变化的,,方便对多个被代理类的代理。。

  • 相关阅读:
    Java Excel导入
    Git在Eclipse中忽略文件提交
    Git客户端安装(仅限windows用户)
    Java输出流文件下载
    Centos6.3源码安装Mysql-5.5.34
    Centos6.3安装Mongodb2.2.4
    Jacob操作Word各格式转换参数
    sublime text3使用小结
    获得select下拉框的值
    sublim text3 配置
  • 原文地址:https://www.cnblogs.com/henuliulei/p/9324391.html
Copyright © 2020-2023  润新知