代理模式

代理模式概念:
通常我们不想或者不能直接调用某一类,可以设计出另外一个类来代理我们想调用的类,这种替代其他类执行的模式叫代理模式

代理模式的角色分为三种:真实类  代理类   抽象接口

普通的代理模式实现方法:
原理:实质上是代理类事先有一个真实类的引用,故代理类里面可以调用真实类的方法
//抽象代类或接口

public interface Subject{
        public void method();
    }

    //真实类
    public class RealSubject implements Subject{

        @Override
        public void method() {
            // TODO Auto-generated method stub
            System.out.println("i am a real subject");
        }

    }

    //代理类
    public class MyProxy implements Subject{
        private Subject ss;

        public MyProxy(){
            ss = new RealSubject();
        }


        @Override
        public void method() {
            // TODO Auto-generated method stub
            beforeMethod();
            ss.method();
            afterMethod();
        }

        public void afterMethod(){
            System.out.println("after.....");
        }

        public void beforeMethod(){
            System.out.println("before.....");
        }


    }
但是,这有也缺点:创建代理类里面的真是累引用时,必须真实类存在,而且一个类对应一个代理类,这也是对类的数量一个冲击,况且,如果实现不知道真是累的时候,我们又该如何去代理呢????  这就引入下面的动态代理模式:

动态代理模式:
动态代理模式和上面差不多类似,不同的是在获取真实类的引用时,我们使用JAVA反射机制动态获取的,而不是直接new,事先创建好
动态代理模式需要用到Proxy和InvocationHandler两个类,前者用用动态获取代理对象,后者用于约束调用者实现

在InvocationHandler,涉及一个重要的方法:
public Object invoke(Object obj, Method method, Object[] para)
第一个是代理类proxy,第二个是我们真实要调用的方法;第三个是方法参数,用于第二个方法参数的

Proxy类产生代理类的方法
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
参数分别是类加载器,通过class文件过去接口,第三个是撒谎那个面的那个handler

实现方法如下:

//代理约束
    public class DynamicSubject implements InvocationHandler{

    private Object o;

    public DynamicSubject(Object o){
        this.o = o;
    }

    @Override
    public Object invoke(Object obj, Method method, Object[] para)
            throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("before");

        method.invoke(o, para);
        System.out.println("after");
        return null;
    }

    }

    //单元测试
    public class TestDynamicProxy {

    @Test
    public void test() {
        RealSubject rs = new RealSubject();
        InvocationHandler ds = new DynamicSubject(rs);
        Class cls = rs.getClass();

        Subject proxy = (Subject) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(), ds);

        proxy.println("Dynamic");
    }

}
posted @ 2015-10-08 21:25  帅气好男人_jack  阅读(6)  评论(0编辑  收藏  举报  来源