千家信息网

Java静态代理和动态代理如何实现

发表于:2024-12-13 作者:千家信息网编辑
千家信息网最后更新 2024年12月13日,这篇文章主要介绍"Java静态代理和动态代理如何实现"的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇"Java静态代理和动态代理如何实现"文章能帮助大家解决问题。
千家信息网最后更新 2024年12月13日Java静态代理和动态代理如何实现

这篇文章主要介绍"Java静态代理和动态代理如何实现"的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇"Java静态代理和动态代理如何实现"文章能帮助大家解决问题。

代理模式

代理模式(Proxy):为其他对象提供一个代理以控制对这个对象的访问。

主要解决:在直接访问对象时带来的问题,比如说:要访问的对象在远程的机器上。在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,或者某些操作需要安全控制,或者需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。

代理模式的元素是:共同接口、代理对象、目标对象。

代理模式的行为:由代理对象执行目标对象的方法、由代理对象扩展目标对象的方法。

代理模式的宏观特性:对客户端只暴露出接口,不暴露它以下的架构。

好处多多:中间隔离了一层,更加符合开闭原则

创建一个接口

/** * @Author: Promsing * @Date: 2021/4/3 - 8:25 * @Description: 买车的接口 * @version: 1.0 */public interface BuyCar {  public void buyCar();}

创建一个实现类

/** * @Author: Promsing * @Date: 2021/4/3 - 8:25 * @Description: 实现类 * @version: 1.0 */public class BuyCarImpl implements BuyCar {  @Override public void buyCar() {  System.out.println("我要买车~~~啦啦啦"); }}

静态代理:

创建一个代理类

 /** * @Author: Promsing * @Date: 2021/4/3 - 8:26 * @Description: 代理类 * @version: 1.0 */public class BuyCarProxy implements BuyCar{ private BuyCar buyCar; //注意事final修饰的关键字 不可修改 //构造函数注入,需要被代理的对象 public BuyCarProxy(final BuyCar buyCar) {  this.buyCar = buyCar; } //静态代理- 的实现方式 @Override public void buyCar() {  System.out.println("不贷款,全款!买车前的准备~~~");  buyCar.buyCar();  System.out.println("买完车了,出去浪~~~"); }}

客户端调用

/** * @Author: Promsing * @Date: 2021/4/3 - 8:36 * @Description: 客户端调用 * @version: 1.0 */public abstract class ProxyTest implements BuyCar {  public static void main(String[] args) {    System.out.println("-+-+-+正常调用-+-+-+");    BuyCar car=new BuyCarImpl();    car.buyCar();     System.out.println("-+-+-+使用静态代理-+-+-+");    BuyCar proxy=new BuyCarProxy(car);    proxy.buyCar();  }}-+-+-+正常调用-+-+-+我要买车~~~啦啦啦 -+-+-+使用静态代理-+-+-+不贷款,全款!买车前的准备~~~我要买车~~~啦啦啦买完车了,出去浪~~~

动态代理:

基于接口的动态代理类

特点:字节码随用随创建,随用随加载

作用:在不修改源码的基础上对方法增强

涉及的类:JDK官方提供的Proxy

如何创建代理对象:使用Proxy类中的newProxyInstance方法

创建代理对象的要求:被代理类至少实现一个接口

newProxyInstance方法的参数

ClassLoader:类加载器,同于加载被代理对象字节码

Class[]:字节码数组---用于让代理对象和被代理对象拥有相同的方法

InvocationHandler:用于提供被增强的代码

/** * @Author: Promsing * @Date: 2021/4/3 - 9:09 * @Description: 描述 形容 * @version: 1.0 */public class DynamicProxy implements InvocationHandler {  private BuyCar object;   public DynamicProxy( BuyCar object) {    this.object = object;  }   /**   *    * @param proxy 代理对象的引用   * @param method 当前执行的方法   * @param args 当前执行方法所需的参数   * @return 和被代理对象方法有相同的返回值   * @throws Throwable   */  @Override  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {    System.out.println("不贷款,全款!买车前的准备~~~");    Object result = method.invoke(object, args);    System.out.println("买完车了,出去浪~~~");    return result;  }}

客户端

 public static void main(String[] args) {       System.out.println("-+-+-+使用基于接口的代理-+-+-+");    //方式一、如不写动态代理类DynamicProxy,可以在这里使用内部类    //声明一个final修饰的对象    /*    final BuyCarImpl car=new BuyCarImpl();    BuyCar proxy=(BuyCar)Proxy.newProxyInstance(car.getClass().getClassLoader(), car.getClass().getInterfaces(), new InvocationHandler() {      @Override      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("不贷款,全款!买车前的准备~~~");        Object result = method.invoke(car, args);        System.out.println("买完车了,出去浪~~~");        return result;      }    });    proxy.buyCar();    */     //方式二、使用DynamicProxy类    //声明一个final修饰的对象    final BuyCarImpl car=new BuyCarImpl();    BuyCar proxy=(BuyCar)Proxy.newProxyInstance(car.getClass().getClassLoader(), car.getClass().getInterfaces(),new DynamicProxy(car));    proxy.buyCar();  }

基于子类的动态代理

特点:字节码随用随创建,随用随加载

作用:在不修改源码的基础上对方法增强

涉及的类:第三方cglib提供的Enhancer

如何创建代理对象:使用Enhancer类中create方法

创建代理对象的要求:被代理类不能是最终类

newProxyInstance方法的参数

Class:用于被指定代理对象的字节码

InvocationHandler:用于提供增强的方法

 public static void main(String[] args) {     //使用基于子类的动态代理    //需要引入Jar包--cglib 本案例使用cglib3.3.0    System.out.println("-+-+-+使用基于子类的代理-+-+-+");    final BuyCarImpl car=new BuyCarImpl();     BuyCar proxy= (BuyCar)Enhancer.create(car.getClass(), new MethodInterceptor() {      @Override      public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {        System.out.println("不贷款,全款!买车前的准备~~~");        Object result = method.invoke(car, args);        System.out.println("买完车了,出去浪~~~");        return result;       }    });     proxy.buyCar();  }

关于"Java静态代理和动态代理如何实现"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注行业资讯频道,小编每天都会为大家更新不同的知识点。

0