zoukankan      html  css  js  c++  java
  • jdk动态代理详解 一 入门

    某个类如何想要采用jdk的动态代理,这个类必须要实现一个接口。

    JDK的动态代理有几个关键的类和接口:

    (1) Proxy: 用来生产代理对象与代理类(com.sun.proxy.$ProxyN)

    生产的代理类就是:

    com.sun.proxy.$ProxyN
    

    N是从0开始的整数

    (2) InvocationHandler:回调处理程序,当代理对象调用某个方法时,就会调用这个接口中的invoke方法

    1. 被代理接口
      package my.annotation.learn;

      public interface ServiceInf {
          
          public void fun01();
          
          public void fun02();
      }
      
    2. 被代理的目标类
      package my.annotation.learn;

      public class TargetClass implements ServiceInf{
      
          @Override
          public void fun01() {
              
              System.out.println("TargetClass->fun01()");
          }
      
          @Override
          public void fun02() {
              System.out.println("TargetClass->fun02()");
          }
      
      }
      
    3. 回调处理程序
      InvocationHandler调用处理程序是一个与代理对象绑定的对象,当在一个代理对象上调用被代理方法时都会调用InvocationHandler实现类的实例上的invoke方法
      package my.annotation.learn;

      import java.lang.reflect.InvocationHandler;
      import java.lang.reflect.Method;
      /**
      InvocationHandler是代理对象的调用处理器要实现的接口
      每一个代理对象都有一个相关联的调用处理器
      当在一个代理对象上调用某个方法时,该方法的调用都会被编码和发送到这个方法的调用处理程序上
      */
      public class MyInvocationHandler implements InvocationHandler{
          
          private TargetClass target;
      
          
          public MyInvocationHandler(TargetClass target) {
              this.target = target;
          }
      
          /**
           * proxy jdk生产的代理对象
           * method 要调用的接口的方法的实例
           * args 调用方法传递的参数
           */
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              System.out.println("代理方法开始执行");
              System.out.println(proxy.getClass().getName());
              System.out.println(method);
              method.invoke(target, args);
              System.out.println("代理方法开始结束");
              return null;
          }
      
      }
      

    4.运行代码

    package my.annotation.learn;
    
    import java.lang.reflect.Proxy;
    
    public class Demo {
    
        public static void main(String[] args) {
            TargetClass target=new TargetClass();
            ServiceInf proxy =(ServiceInf) Proxy.newProxyInstance(Demo.class.getClassLoader(), 
                    new Class<?>[] {ServiceInf.class}, new MyInvocationHandler(target));
            proxy.fun01();
        }
    
    }
    

    运行结果如下:

    代理方法开始执行
    com.sun.proxy.$Proxy0
    public abstract void my.annotation.learn.ServiceInf.fun01()
    TargetClass->fun01()
    代理方法开始结束
    

    从运行结果中我们可以看到 proxy是生产的代理对象,method是接口中的方法

     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
  • 相关阅读:
    java 整合redis缓存 SSM 后台框架 rest接口 shiro druid maven bootstrap html5
    《将博客搬至CSDN》
    前后端分离-定义响应格式化数据
    微服务-Springboot+Redis缓存管理接口代码实现
    java语法
    java后台树形结构展示---懒加载
    后端处理前端传过来的日期的两种方式
    汉字转拼音工具类
    Mybatis的小技巧
    调用高德API,通过输入的地址,如省份、市、区获取经纬度 ,通过输入的经纬度,获取区域详情
  • 原文地址:https://www.cnblogs.com/cplinux/p/14495713.html
Copyright © 2011-2022 走看看