通过JDK动态代理类实现一个类中多种方法的不同增强

打印 上一主题 下一主题

主题 863|帖子 863|积分 2589

1.为什么说JDK动态代理必须要实现当前父接口才能使用

  JDK动态代理是基于接口的代理,它要求目标类(被代理的类)必须实现一个或多个接口。这是因为JDK动态代理是通过创建目标类的接口的代理对象来实现的,代理对象实现了目标接口,并在方法调用时委托给InvocationHandler中的invoke方法来处理。
  在JDK动态代理中,Proxy类的newProxyInstance方法接受一个ClassLoader,一组接口和一个InvocationHandler,然后生成一个代理类的实例。这个代理类实例实现了指定的接口,并将方法调用委托给InvocationHandler中的invoke方法。
  自我结论:可能是因为比如生成的$Proxy代理类如果没有父接口 那他内部也不知道通过InvocationHandler来调用谁来进行增强了 还有就是可能有一些决策问题。
2.JDK动态代理的$Proxy实现
  Cat父接口
  1. //父接口
  2. interface Cat {
  3.     //开车
  4.     void drive();
  5.     //下车
  6.     void off();
  7. }
复制代码
  InvocationHandler接口
  1. interface InvocationHandler {
  2.     //代理类,代理方法,代理方法参数  
  3.     Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
  4. }
复制代码
  $Proxy0代理类
  1. class $Proxy0 implements Cat {
  2.     private InvocationHandler invocationHandler;
  3.     private Map<String, Method> methods;
  4.     public $Proxy0(InvocationHandler invocationHandler) {
  5.         this.invocationHandler = invocationHandler;
  6.         this.methods = new HashMap<>();
  7.         try {
  8.             methods.put("drive", Cat.class.getMethod("drive"));
  9.             methods.put("off", Cat.class.getMethod("off"));
  10.         } catch (NoSuchMethodException e) {
  11.             throw new RuntimeException(e);
  12.         }
  13.     }
  14.     @Override
  15.     public void drive() {
  16.         try {
  17.             invocationHandler.invoke(this, methods.get("drive"), new Object[0]);
  18.         } catch (Throwable e) {
  19.             throw new RuntimeException(e);
  20.         }
  21.     }
  22.     @Override
  23.     public void off() {
  24.         try {
  25.             invocationHandler.invoke(this, methods.get("off"), new Object[0]);
  26.         } catch (Throwable e) {
  27.             throw new RuntimeException(e);
  28.         }
  29.     }
  30. }
复制代码
  CustomLogicHandler 多个方法不同增强
  1. class CustomLogicHandler implements InvocationHandler {
  2.     private Object target;
  3.     private Map<String, Runnable> methodEnhancements;
  4.     public CustomLogicHandler(Object target) {
  5.         this.target = target;
  6.         this.methodEnhancements = new HashMap<>();
  7.         methodEnhancements.put("drive", () -> System.out.println("开车增强"));
  8.         methodEnhancements.put("off", () -> System.out.println("下车增强"));
  9.     }
  10.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  11.         // 根据方法名获取增强逻辑
  12.         Runnable enhancement = methodEnhancements.get(method.getName());
  13.         if (enhancement != null) {
  14.             enhancement.run();
  15.         }
  16.         // 委托给目标对象执行原方法
  17.         Object result = method.invoke(target, args);
  18.         return result;
  19.     }
  20. }
复制代码
 
  Fute实现类(待增强类)
  1. class FuTe implements Cat {
  2.     @Override
  3.     public void drive() {
  4.         System.out.println("我要开始开车了");
  5.     }
  6.     @Override
  7.     public void off() {
  8.         System.out.println("我要下车了");
  9.     }
  10.     public static void main(String[] args) {
  11.         Cat realObject = new FuTe();
  12.         CustomLogicHandler customLogicHandler = new CustomLogicHandler(realObject);
  13.         Cat proxyObject = (Cat) new $Proxy0(customLogicHandler);
  14.         proxyObject.drive();
  15.         System.out.println("------");
  16.         proxyObject.off();
  17.     }
  18. }
复制代码
  总结:在这个例子中,CustomLogicHandler中的methodEnhancements存储了不同方法的增强逻辑,而不再使用if语句。在$Proxy0中的methods也类似地存储了不同方法的Method对象。这种方式可以更灵活地处理不同方法的增强逻辑,而不需要使用大量的if语句。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

冬雨财经

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表