java静态代理和动态代理

原稿链接:http://www.orlion.ga/207/

平、代理模式

    代理模式是时常采取的设计模式,代理模式是深受指定对象提供摄对象。由代理对象来决定具体对象的援。

    代理模式涉及到的角色:

     
  抽象主题角色:声明了代理主题和真实性主题的官接口,使另要真正主题的地方都能因此代理主题代替。

  1.    
    代理主题角色:含有真正主题的援,从而得以于其它时刻操作实际主题,代理主题功过提供与真实性主题相同之接口,使它可随时代替真实主题。代理主题通过拥有真实主题的援,不但可以操纵真实主题的创建或者去,可以在真实主题叫调用前进行阻拦,或于调用后展开一些操作。

       真实代理对象:定义了代办角色所表示的切切实实目标。

    (设计模式是通用的)

    按照代理创建的时代代理类可以分成两栽:

        静态代理:由程序员创建或者一定工具自动生成源代码,再针对那个编译。在程序运行前,代理类的.class文件就已经在        了。

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

    

老二、静态代理

    Talk is cheap,show me the code

    首先定义个酒厂的接口:

    WineFactory.java

    package ml.orlion.proxy;    
    
    public interface WineFactory {
    
        public void sell();
    }

    然后再次定义一个酒厂类实现者接口:

    WineFactoryImpl.java

    package ml.orlion.proxy;

    public class WineFactoryImpl implements WineFactory{
    
        @Override
        public void sell() {
            System.out.println("卖酒");
        }
        
    }

    然后定义一个代理类,对酒厂进行代理:

    WineFactoryProxy.java

    package ml.orlion.proxy;
    /**
     * 代理类
     * 对WineFactoryImpl进行代理
     */
    public class WineFactoryProxy implements WineFactory{
        
        private WineFactory winef;
    
        public WineFactoryProxy(WineFactory winef){
            this.winef = winef;
        }
    
        @Override
        public void sell() {
            System.out.println("卖酒之前...");
            winef.sell();
            System.out.println("卖酒之后...");
        }
    }

 

其三、动态代理

    由静态代理的代码可以望静态代理只能对一个接口进行劳动,如果项目受到有不少个接口,那么一定会起过多的代办。这时候就用因此到动态代理,由一个代理类成就具有的代理功能。动态代理类的许节码在程序运行时由Java反射机制动态变化,无需程序员手工编制它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的但是扩展性,因为Java
反射机制好转变任意档次的动态代理类。

    JDK动态代理中隐含一个InvocationHandler接口和一个Proxy类

    (1)InvocationHandler接口

    public interface InvocationHandler {     
        public Object invoke(Object proxy,Method method,Object[] args) throws Throwable; 
    }

    其中Object porxy:是为摄的对象

    Method method:要调用的计

    Object[] args:要调用的艺术的参数

    (2)Proxy类

    Proxy类是专程就代理的操作类,可以通过此类为一个或者多单接口动态地转移实现类似,此类提供了之类的操作方法:

    public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,     InvocationHandler h)  throws IllegalArgumentException

    其中ClassLoader loader:是近似加载器;

    (在java中一言九鼎出三栽恍若加载器:

        Booststrap
ClassLoader:此加载器采用C++编写,一般开发中是看不到的;

            Extendsion
ClassLoader:用来进行扩展类的加载,一般对应的凡jrelibext目录中之类似; 

            AppClassLoader:(默认)加载classpath指定的好像,是最常使用的凡一样种植加载器。          

    )

    Class<?>[] interfaces:得到不折不扣接口;

    InvocationHandler h:得到InvocationHandler接口的子类C++实例;

    code:

     WineFactory.java和WineFactoryImpl.java和静态代理的代码相同。

    WineFactoryInvocationHandler.java:

    package ml.orlion.proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    /**
     * JDK动态代理类
     * 对WineFactoryImpl进行代理
     */
    public class WineFactoryInvocationHandler implements InvocationHandler{
    
        private Object target;
    
        @Override
        public Object invoke(Object porxy, Method m, Object[] args) throws Throwable {
            
            Object result = null;
            
            beforeMethod();
            // 执行
            result = m.invoke(target, args);
            
            afterMethod();
            return result;
        }
        
        public void beforeMethod(){
            System.out.println("卖酒之前...");
        }
        
        public void afterMethod(){
            System.out.println("卖酒之后...");
        }
        
        public Object getTarget() {
            return target;
        }
    
        public void setTarget(Object target) {
            this.target = target;
        }
    }

    测试:

    // 产生一个被代理对象
    WineFactory wf = new WineFactoryImpl();
    // 将被代理对象交给InvocationHandler
    WineFactoryInvocationHandler wfih = new WineFactoryInvocationHandler();
    wfih.setTarget(wf);
    // 根据被代理对象产生一个代理
    WineFactory wfp = (WineFactory)Proxy.newProxyInstance(wf.getClass().getClassLoader(), wf.getClass().getInterfaces(), wfih);
    wfp.sell();

    

    除了JDK动态代理外尚出同一种cglib动态代理,具体但参考文章(本文参考):http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html