带你了解静态代理和动态代理的区别

使用代理的目的是可以实现在目标对象的方法作拦截、过滤、预处理,对目标对象进行封装。根据代理类创建的时期又可以分为静态代理和动态代理。

一、静态代理

  1. 只代理一个类;
  2. 事先知道要代理的是什么;
  3. 实现与目标对象一样的接口;
  4. 由程序员创建或由特定工具自动生成源代码。

静态代理的例子可见如下代码:

//接口
public interface IAnimal {

    void doSomeThing();

    void doBThing();

}
//目标对象
public class People implements IAnimal {

    @Override
    public void doSomeThing() {
        System.out.println("I'm People, I'm working!");
    }

    @Override
    public void doBThing() {
        System.out.println("I'm People, I'm doing B thing!");
    }
}
//静态代理类
public class PeopleQuietProxy implements IAnimal {

    private People realObject;

    public PeopleQuietProxy(People people){
        this.realObject = people;
    }

    @Override
    public void doSomeThing() {
        System.out.println("before invoke realMethod...");
        realObject.doSomeThing();
        System.out.println("after invoke realMethod...");
    }

    @Override
    public void doBThing() {
        System.out.println("before invoke realMethod...");
        realObject.doBThing();
        System.out.println("after invoke realMethod...");
    }
}

二、动态代理

  1. 可代理多个实现类;
  2. 事先不知道要代理的是什么,只有在运行时才能确定;
  3. 一种动态代理是通过实现JDK的InvocationHandler接口的invoke方法,然后调用Proxy.newProxyInstance得到代理对象,代理的是接口;
    还有一种动态代理CGLIB,代理的是类,不需要业务类继承接口,通过派生的子类来实现代理。通过在运行时,动态修改字节码达到修改类的目的。

动态代理类可见如下代码:

public class PeopleProxy implements InvocationHandler {

    private Object realObject;

    public Object getInstance(Object realObject){
        this.realObject = realObject;
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), realObject.getClass().getInterfaces(), this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("before invoke realMethod...");
        Object result = method.invoke(realObject, args);
        System.out.println("after invoke realMethod...");
        return result;
    }
}

//测试对象
public class TestPeopleProxy {

    public static void main(String[] args) {
        PeopleProxy proxy = new PeopleProxy();
        IAnimal animal = (IAnimal) proxy.getInstance(new People());
        animal.doBThing();
        animal.doSomeThing();
    }
}

从动态代理类PeopleProxy可以看到虽然类型跟People有关,但是类中却跟People没有一毛钱关系,即在创建和编译的时候,生成class文件之前都不知道目标对象是什么,而是在测试类中main方法运行的时候才从proxy.getInstance传入的参数得到接口信息,然后生成代理对象,之后就可以使用这个代理对象了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值