嗯? 听说你还搞不懂静态代理和动态代理?

静态代理

  • 静态代理其实就是在程序运行之前,提前写好被代理方法的代理类,编译后运行。
  • 在程序运行之前,class已经存在。
    下面我们实现一个静态代理demo:
    img
步骤
  • 创建一个目标接口
  • 目标接口实现类
  • 写一个代理类实现目标接口,初始化时将目标放入
  • 最后写一个测试类测试即可
代码
package Proxy;
/**静态代理*/

//测试类
public class StaticProxy {
    public static void main(String[] args) {
        TargetImpl target = new TargetImpl();
        Proxy proxy = new Proxy(target);
        System.out.println(proxy.execute());
    }
}

//目标接口
interface Target{
    String execute();
}

//目标实现类
class TargetImpl implements Target{
    //重写方法
    @Override
    public String execute() {
        System.out.println("目标被执行");
        return "execute";
    }
}

//代理类
class Proxy implements Target{
    //定义目标属性
    private Target target;
    //构造函数,参数为目标
    public Proxy(Target target){
        this.target=target;
    }

    @Override
    public String execute() {
        System.out.println("代理类执行");
        //执行目标接口的方法
        String res = this.target.execute();
        return res;
    }
}

运行结果

代理类执行
目标被执行
execute

静态代理需要针对被代理的方法提前写好代理类,如果被代理的方法非常多则需要编写很多代码,因此,对于上述缺点,通过动态代理的方式进行了弥补。

动态代理

动态代理主要是通过反射机制,在运行时动态生成所需代理的class.

img

步骤

  • 写一个目标接口和对应的目标实现类

  • 代理处理类

    • 目标属性
    • 构造方法
    • 实现InvocationHandler,重写invoke方法
  • 测试:

    • 实例被代理类

    • 实例代理处理类

    • Proxy.newProxyInstance(被代理类的加载器,被代理类接口,代理处理类实例)生成代理类

    • 代理类实现方法

package Proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/*测试类*/
public class DynamicProxyDemo {
    public static void main(String[] args) {
        //实例化目标实现类
        TargetImpl2 target = new TargetImpl2();
        //实例化代理处理类,将target放入参数
        DynamicProxyHandler handler = new DynamicProxyHandler(target);
        //使用reflect包下的Proxy.newProxyInstance新建动态代理类
        //参数:类加载器,接口,处理类
        Target2 proxySubject = (Target2) Proxy.newProxyInstance(TargetImpl2.class.getClassLoader(), TargetImpl2.class.getInterfaces(), handler);
        //代理类直接方法
        String res = proxySubject.execute();
        System.out.println(res);
    }

}

/*目标类*/
interface Target2{
    String execute();
}

/*目标实现类*/
//实现Target接口
class TargetImpl2 implements Target2{
    @Override
    public String execute() {
        System.out.println("目标类被执行");
        return "target-execute";
    }
}

/*代理处理类*/
//实现InvocationHandler接口
class DynamicProxyHandler implements InvocationHandler {

    //定义目标类
    private Target2 target2;
    //构造方法
    public DynamicProxyHandler(Target2 target2){
        this.target2=target2;
    }

    //重写invoke方法,
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println("=====before=====");
        Object res = method.invoke(target2, args);
        System.out.println("=====after=====");
        return res;
    }
}

  • 无论是动态代理还是静态带领,都需要定义接口,然后才能实现代理功能。
  • 这同样存在局限性,因此,为了解决这个问题,出现了第三种代理方式:cglib代理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WalkerShen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值