1

(1)什么是代理?

大道理上讲代理是一种软件设计模式,目的地希望能做到代码重用。具体上讲,代理这种设计模式是通过不直接访问被代理对象的方式,而访问被代理对象的方法。这个就好比 商户---->明星经纪人(代理)---->明星这种模式。我们可以不通过直接与明星对话的情况下,而通过明星经纪人(代理)与其产生间接对话

(2)什么情况下使用代理?

a. 设计模式中有一个设计原则是开闭原则,是说对修改关闭对扩展开放,我们在工作中有时会接手很多前人的代码,里面代码逻辑让人摸不着头脑(sometimes the code is really like shit),这时就很难去下手修改代码,那么这时我们就可以通过代理对类进行增强。
b. 我们在使用RPC框架的时候,框架本身并不能提前知道各个业务方要调用哪些接口的哪些方法 。那么这个时候,就可用通过动态代理的方式来建立一个中间人给客户端使用,也方便框架进行搭建逻辑,某种程度上也是客户端代码和框架松耦合的一种表现。

(3)静态代理和动态代理
静态代理比较简单,主要是多态实现,这里主要记录下动态代理

定义代理父类

package cn.crawler.split.test.proxy;

/**
 * Created by liang.liu04@hand-china.com
 * on 2018/7/12
 */
public interface Father {
    public void rent();

    public void hello(String str);
}

子类

/**
 * Created by liang.liu04@hand-china.com
 * on 2018/7/12
 */
public class Son implements Father {
    @Override
    public void rent()
    {
        System.out.println("I want to rent my house");
    }

    @Override
    public void hello(String str)
    {
        System.out.println("hello: " + str);
    }
}

代理类

package cn.crawler.split.test.proxy;

import org.springframework.cglib.proxy.InvocationHandler;

import java.lang.reflect.Method;

/**
 * Created by liang.liu04@hand-china.com
 * on 2018/7/12
 */
public class DynamicProxy implements InvocationHandler
{
    // 这个就是我们要代理的真实对象
    private Object subject;

    //    构造方法,给我们要代理的真实对象赋初值
    public DynamicProxy(Object subject)
    {
        this.subject = subject;
    }

    @Override
    public Object invoke(Object object, Method method, Object[] args)
            throws Throwable
    {
        //  在代理真实对象前我们可以添加一些自己的操作
        System.out.println("before rent house");

        System.out.println("Method:" + method);

        //    当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用
        method.invoke(subject, args);

        //  在代理真实对象后我们也可以添加一些自己的操作
        System.out.println("after rent house");

        return null;
    }

}

测试类

package cn.crawler.split.test.proxy;

import org.springframework.cglib.proxy.InvocationHandler;
import org.springframework.cglib.proxy.Proxy;

/**
 * Created by liang.liu04@hand-china.com
 * on 2018/7/12
 */
public class MyProxyTest {
    public static void main (String[] stra){

        //代理对象
        Father son = new Son();
        System.out.println(son.getClass());

        InvocationHandler handler  = new DynamicProxy(son);

        Father father = (Father)Proxy.newProxyInstance(handler.getClass().getClassLoader(), son.getClass().getInterfaces(), handler);
        System.out.println(father.getClass().getName());
        father.rent();
        father.hello("world");


    }
}

测试结果:

class cn.crawler.split.test.proxy.Son
org.springframework.cglib.proxy.Proxy$ProxyImpl$$EnhancerByCGLIB$$f4f3d897
before rent house
Method:public abstract void cn.crawler.split.test.proxy.Father.rent()
I want to rent my house
after rent house
before rent house
Method:public abstract void cn.crawler.split.test.proxy.Father.hello(java.lang.String)
hello: world
after rent house


crawler
327 声望79 粉丝

专注技术多年,曾任职京东,汉得等公司主研