美文网首页
静态代理与动态代理

静态代理与动态代理

作者: SmogZhang | 来源:发表于2017-12-08 22:20 被阅读0次

    在开始为Spring做记录之前,我把之前学代理的笔记整理一番,方便写AOP的时候拿出来看看。

    首先搞懂什么是代理,谁代理谁,谁又被谁代理;然后清楚代理的目的,代理的好处。这是我的方向。

    简单点说:当对象a需要和对象b合作时,b可能不太方便直接与a碰面(更多的是为了解耦,或者为了保护b)。这时候就出现了对象c,它是对象b的代理,由c和a直接打交道。

    注意三点:
    • a可以不知道b的存在
    • 干实事的是b
    • c可以在b做事前后调用自己的方法
    ps:代理对象一般要和被代理对象实现同一个接口,为了保证行为的一致性。

    静态代理

    先贴出代码:

    public class WangPoStatic implements KindWomen{
        
        private String name = "王婆";
        private KindWomen kindWomen;
        
        public WangPoStatic(KindWomen kindWomen) {
            this.kindWomen = kindWomen;
        }
        
        public void makeEyesToMen() {
            getMoneyFromMen();
            kindWomen.makeEyesToMen();
            dealWithLastThing();
        }
        
        @Override
        public void happyWithMen() {
            getMoneyFromMen();
            kindWomen.happyWithMen();
            dealWithLastThing();
        }
        
        //代理类动作
        private void getMoneyFromMen() {
            System.out.println(name + "收好处了。。。");   
        }
        
        private void dealWithLastThing() {
            System.out.println(name + "善后了。。。");    
        }
    }
    

    很明显了,通过构造方法注入的就是真实对象,当通过代理类调用公共接口中的方法时,真正干活的是真实对象,只是被隐藏起来了。

    动态代理

    上面的静态代理就可以搞明白了我们原先的疑问。即代理类在委托类(真实对象)执行前后进行自己的操作。但是静态代理并不能满足开发人员的要求,原因是若是公共接口有很多方法呢?那岂不是每个方法都要手动操作一番?

    这里介绍JDK中的一种动态代理方式,这种代理方式能在运行期间动态地创建代理对象。

    实现步骤:
    i:创建实现接口InvocationHandler的类,作为调用处理器;
    ii:创建被代理的类以及接口;
    iii:通过Proxy的静态方法创建一个代理

    newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h) 
    

    iV: 通过代理调用方法

    贴出部分代码:
    // 实现了 InvocationHandler 接口的处理器
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    //第一个参数是代理对象,第二个是被调用的方法对象,第三个是方法对象执行invoke时需要的参数
            getMoneyFromMen();
            Object object = method.invoke(kw, args);   //kw 为委托对象
            dealWithLastThing();
            return object;
        }
    
    //test方法
    KindWomen kinWomen = new PanJinlian(); //真实对象  (根据真实对象 创建不同的代理对象)
            //创建代理对象
            KindWomen proxyKw = null;
            WangPoDyn wpd = new WangPoDyn(kinWomen);
            Object proxyInstance = Proxy.newProxyInstance(KindWomen.class.getClassLoader(), Ruhua.class.getInterfaces(), wpd);
            if(proxyInstance != null && proxyInstance instanceof KindWomen) {
                proxyKw = (KindWomen) proxyInstance;
            }
            proxyKw.makeEyesToMen();
            System.out.println("******************");
            proxyKw.happyWithMen();
    

    代理对象调用方法时会回到调用处理器的invoke()方法里面。这个处理器对象中的invoke方法可以分为两部分:一部分是 method.invoke(obj, args) 即真实对象干活,另一部分是在其前后执行的其它方法,在AOP中叫做连接点。

    相关文章

      网友评论

          本文标题:静态代理与动态代理

          本文链接:https://www.haomeiwen.com/subject/hcuyixtx.html