【代理模式】动态代理-简单例子

本文详细介绍了如何使用Java的Proxy类和InvocationHandler接口创建动态代理,演示了如何在UserService接口和UserServiceImpl类的基础上添加代理功能,以及在实际应用中的AOP和RPC场景中的作用。
摘要由CSDN通过智能技术生成

这段Java代码使用了Java的Proxy类来动态地创建一个代理实例。代理模式是设计模式中的一种,用于在不修改原始类的情况下增加额外的功能或控制对原始对象的访问。在Java中,我们可以使用Proxy类和InvocationHandler接口来实现这种动态代理。

目录

一、目录结构

二、各个部分

三、测试


一、目录结构

二、各个部分

(1)首先定义UserService接口和UserServiceImpl类,并且UserServiceImpl类实现了UserService接口。

public interface UserService {
  public void add();
  public void delete();
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
public class UserServiceImpl implements UserService{

  @Override
  public void add() {
    System.out.println("增加了一个用户");
  }

  @Override
  public void delete() {
    System.out.println("删除了一个用户");
  }
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

(2)定义了一个名为 ProxyInvocationHandler 的类,该类实现了 Java 的 InvocationHandler 接口。这个类用于创建动态代理,并处理代理对象上的方法调用。动态代理是一种在运行时创建代理类和对象的技术,而不需要在编译时生成额外的类文件。

InvocationHandler是Java动态代理的核心接口,用于处理代理实例上的方法调用,并将其转发到指定的对象。


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

public class ProxyInvocationHandler implements InvocationHandler {
  private Object target;  // 被代理的接口

  public void setTarget(Object target){
    this.target = target;
  }

  // 生成得到的代理类:一个新的代理对象被创建出来,它实现了target的所有接口,并且所有的方法调用都会被转发到当前对象的invoke方法
  public Object getProxy(){
    return Proxy.newProxyInstance(this.getClass().getClassLoader(),  // 需要用来加载新创建的代理类的类加载器
      target.getClass().getInterfaces(),   // 被代理的接口
      this);  // 当前类实现了InvocationHandler接口
  }


  // 处理代理实例,并返回结果
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    log(method.getName());
    Object result = method.invoke(target, args);
    return result;
  }

  public void log(String str){
    System.out.println("调用了" + str + "方法");
  }
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

setTarget()方法:用于设置 target 成员变量的值,即被代理的对象。

log()方法: 用于在控制台上打印日志,表明哪个方法被调用了。

 getProxy()方法:使用 Proxy.newProxyInstance 方法来创建一个新的代理对象。这个代理对象实现了 target 对象所实现的所有接口,并且所有的方法调用都会被转发到当前对象的 invoke 方法。

 invoke(Object proxy, Method method, Object[] args)方法:是 InvocationHandler 接口中必须实现的方法。当代理对象上的方法被调用时,这个方法会被执行。

 数说明:

  1.  this.getClass().getClassLoader():这是获取当前对象类(this)的类加载器。类加载器用于动态加载类,Proxy.newProxyInstance的第一个参数就是需要用来加载新创建的代理类的类加载器。
  2.  target.getClass().getInterfaces():这里获取了target对象类实现的所有接口。Proxy.newProxyInstance的第二个参数是一个接口数组,这些接口会被代理类实现。通常,被代理的对象(即target)是一个接口的实现,这样代理就可以和被代理对象有相同的接口。
  3.  this:这里假定当前类实现了InvocationHandler接口,并将当前对象(this)作为InvocationHandler的实例传递给Proxy.newProxyInstanceInvocationHandler是处理代理实例上方法调用的接口,其invoke方法会被调用来处理每个方法调用。整个调用的结果是,一个新的代理对象被创建出来,它实现了target的所有接口,并且所有的方法调用都会被转发到当前对象的invoke方法。

请注意,this必须是一个InvocationHandler的实现,而target应该是一个实现了至少一个接口的对象。如果这些前提条件不满足,代码将无法正常工作。

(3)

public class Client {
  public static void main(String[] args) {
    UserServiceImpl userService = new UserServiceImpl();  // 真实角色
    ProxyInvocationHandler pih = new ProxyInvocationHandler();  // 代理角色,不存在
    pih.setTarget(userService);  // 设置要代理的对象

    UserService proxy = (UserService) pih.getProxy();  // 动态生成代理类
    proxy.add();
  }
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

流程:

  1. 创建了一个UserServiceImpl对象,它是真实的服务实现类(即被代理的对象)
  2. 创建一个ProxyInvocationHandler对象
  3. 这里将userService设置为代理要转发方法调用的目标对象。这意味着当我们通过代理调用方法时,这些方法调用实际上会被转发到userService对象上。
  4. ProxyInvocationHandler对象获取一个动态生成的代理对象

三、测试

运行代码的结果:

这是一个使用动态代理的简单例子,你可以通过它来拦截和修改对被代理对象的方法调用。这在很多场景中都非常有用,比如AOP(面向切面编程)、RPC(远程过程调用)框架等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

水w

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

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

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

打赏作者

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

抵扣说明:

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

余额充值