程序员Java 杂谈

Spring框架_静态代理 动态代理

2017-11-16  本文已影响162人  Miss_差不多

什么是代理

我们大家都知道微商代理,简单地说就是代替厂家卖商品,厂家“委托”代理为其销售商品。关于微商代理,首先我们从他们那里买东西时通常不知道背后的厂家究竟是谁,也就是说,“委托者”对我们来说是不可见的;我们把微商代理和厂家进一步抽象,前者可抽象为代理类,后者可抽象为委托类(被代理类)。通过使用代理,通常有两个优点,并且能够分别与我们提到的微商代理的两个特点对应起来:
优点一:可以隐藏委托类的实现;
优点二:可以实现客户与委托类间的解耦,在不修改委托类代码的情况下能够做一些额外的处理。

静态代理

由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。若代理类在程序运行前就已经存在,那么这种代理方式被成为 静态代理 ,这种情况下的代理类通常都是我们在Java代码中定义的。 通常情况下, 静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类。 下面我们用Vendor类代表生产厂家,Business类代表微商代理,来介绍下静态代理的简单实现,委托类和代理类都实现了Sell接口.:

//接口
public interface Sell {
  void sell();
  
}
public class Business implements Sell{

    public void sell() {
        System.out.println("代理买东西");
        
    }

}
public class Vendor implements Sell{

    public void sell() {
        System.out.println("厂家买东西");
        
    }
   
}
public class Test {
    
    public static void main(String[] args) {
        Sell s=new Vendor();
        s.sell();
    }

}

测试结果:厂家买东西

静态代理类优缺点

优点:业务类只需要关注业务逻辑本身,保证了业务类的重用性。这是代理的共有优点。
缺点:
1)代理对象的一个接口只服务于一种类型的对象,如果要代理的方法很多,势必要为每一种方法都进行代理,静态代理在程序规模稍大时就无法胜任了。
2)如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。

动态代理

代理类在程序运行时创建的代理方式被成为 动态代理。 也就是说,这种情况下,代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的。相比于静态代理, 动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用修改每个代理类的函数。 这么说比较抽象,下面我们结合一个实例来介绍一下动态代理的这个优势是怎么体现的

//代理商
public class Business implements InvocationHandler{

    //指示
    private Object obj;
    
    
//  public void sell() {
//      System.out.println("代理买东西");
//      
//  }

    public Object getObj() {
        return obj;
    }


    public void setObj(Object obj) {
        this.obj = obj;
    }


    public Business(Object obj) {
        super();
        this.obj = obj;
    }


    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        method.invoke(obj, args);
        //System.out.println("代理买东西");
        return obj;
    }

}

测试

public class Test {
    
    public static void main(String[] args) {
        
        Business b=new Business(new Vendor());
        Sell s=(Sell)Proxy.newProxyInstance(Vendor.class.getClassLoader(), Vendor.class.getInterfaces(), b);
        s.sell();
    }

}

测试结果:厂家买东西

动态代理实现步骤

具体步骤是:
a. 实现InvocationHandler接口创建自己的调用处理器
b. 给Proxy类提供ClassLoader和代理接口类型数组创建动态代理类
c. 以调用处理器类型为参数,利用反射机制得到动态代理类的构造函数
d. 以调用处理器对象为参数,利用动态代理类的构造函数创建动态代理类对象

动态代理的优点

优点:
动态代理与静态代理相比较,最大的好处是接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler.invoke)。这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。

推介:
http://doushini.iteye.com/blog/1847913
http://www.jb51.net/article/95685.htm

上一篇 下一篇

猜你喜欢

热点阅读