您的位置:首页 > 编程语言 > Java开发

静态代理和动态代理

2014-04-17 14:41 295 查看
所谓代理,可以认为是 客户无法直接与服务端交流,那么就需要一个媒介来处理他们之间的会面。思想比较简单,但是遇到真实情况下,静态代理比较容易理解,动态代理值得学习,想起以前别人的一些程序还是比较容易理解。

一)静态代理

1:

public abstract class Subject

{

    public abstract void request();

}

2:

public class RealSubject extends Subject

{

    public void request()

    {

        System.out.println("From real subject.");

    }

}:

3:

public class ProxySubject extends Subject

{

    private RealSubject realSubject; //代理角色内部引用了真实角色

    

    public void request()

    {

        this.preRequest(); //在真实角色操作之前所附加的操作

        

        if(null == realSubject)

        {

            realSubject = new RealSubject();

        }

        

        realSubject.request(); //真实角色所完成的事情

        

        this.postRequest(); //在真实角色操作之后所附加的操作

    }

    private void preRequest()

    {

        System.out.println("pre request");

    }

    

    private void postRequest()

    {

        System.out.println("post request");

    }

}

4:

public class Client

{

    public static void main(String[] args)

    {

        Subject subject = new ProxySubject();

        

        subject.request();

    }

}
二)动态代理

1:

public interface Subject

{

    public void request();

}

2:

public class RealSubject implements Subject

{

    public void request()

    {

        System.out.println("From real subject!");

    }

}

3:

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

/**

 * 该代理类的内部属性是Object类型,实际使用的时候通过该类的构造方法传递进来一个对象

 * 此外,该类还实现了invoke方法,该方法中的method.invoke其实就是调用被代理对象的将要

 * 执行的方法,方法参数是sub,表示该方法从属于sub,通过动态代理类,我们可以在执行真实对象的方法前后

 * 加入自己的一些额外方法。

 *

 */

public class DynamicSubject implements InvocationHandler

{

    private Object sub;

    

    public DynamicSubject(Object obj)

    {

        this.sub = obj;

    }

    

    public Object invoke(Object proxy, Method method, Object[] args)

            throws Throwable

    {

        System.out.println("before calling: " + method);

        

        method.invoke(sub, args);

        

        System.out.println(args == null);

        

        System.out.println("after calling: " + method);

        

        return null;

    }

    

}

4:

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.util.List;

import java.util.Vector;

public class VectorProxy implements InvocationHandler

{

    private Object proxyObj;

    public VectorProxy(Object obj)

    {

        this.proxyObj = obj;

    }

    public static Object factory(Object obj)

    {

        Class<?> classType = obj.getClass();

        return Proxy.newProxyInstance(classType.getClassLoader(),

                classType.getInterfaces(), new VectorProxy(obj));

    }

    

    public Object invoke(Object proxy, Method method, Object[] args)

            throws Throwable

    {

        System.out.println("before calling: " + method);

        

        if(null != args)

        {

            for(Object obj : args)

            {

                System.out.println(obj);

            }

        }

        

        Object object = method.invoke(proxyObj, args);

        

        System.out.println("after calling: " + method);

        

        return object;

    }

    

    public static void main(String[] args)

    {

        List v = (List)factory(new Vector());

        

        System.out.println(v.getClass().getName());

        

        v.add("New");

        v.add("York");

        

        System.out.println(v);

        

        v.remove(0);

        System.out.println(v);

        

    }

}

5:

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Proxy;

public class Client

{

    public static void main(String[] args)

    {

        RealSubject realSubject = new RealSubject();

        InvocationHandler handler = new DynamicSubject(realSubject);

        Class<?> classType = handler.getClass();

        // 下面的代码一次性生成代理

        Subject subject = (Subject) Proxy.newProxyInstance(classType

                .getClassLoader(), realSubject.getClass().getInterfaces(),

                handler);

        subject.request();

        System.out.println(subject.getClass());

    }

}

Java开发包中包含了对动态代理的支持,但是其实现只支持对接口的的实现。

其实现主要通过是java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。可以这样想象:编译期间我们不知道有多少类,只有在运行期间利用反射机制动态的生成一些class。这就是所谓的动态代理,表面做到了灵活性,但是我始终觉得比较耗资源。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 代理模式