静态代理与动态代理

在开始为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中叫做连接点。

你可能感兴趣的:(静态代理与动态代理)