JDK 动态代理 - 使用方法

JDK动态代理使用方法

JDK 动态代理针对接口,只有实现了接口的类能使用JDK动态代理

代码实例

public class JdkProxyDemo {

    interface Foo {
        void foo();
    }

    static class Target implements Foo {
        public void foo() {
            System.out.println("target foo");
        }
    }

    public static void main(String[] param) {
        // 目标对象
        Target target = new Target();
        // 代理对象
        Foo proxy = (Foo) Proxy.newProxyInstance(
                Target.class.getClassLoader(), new Class[]{Foo.class},
                (p, method, args) -> {
                    System.out.println("proxy before...");
                    Object result = method.invoke(target, args);
                    System.out.println("proxy after...");
                    return result;
                });
        // 调用代理
        proxy.foo();
    }
}

上面代码实例中,有个静态内部类Target,有个接口Foo,Target类实现了Foo接口
现在要对Target类中的Foo接口方法foo,进行增强
调用官方提供的API,Proxy.newProxyInstance,传入相应参数后获得一个代理对象

分析参入的参数

传入的参数总共有三个

第一个参数 要求我们传入一个类加载器,因为代理类是没有源码的,而是在运行期间直接生成代理类的字节码,生成的字节码需要被加载后才能运行,因此需要传入一个类加载器来做加载操作,可以直接传入被代理类的类加载器

第二个参数 要求传入一个接口数组,用于指定需要增强的方法是哪些。一个类可以实现很多个接口,传入了哪些接口,那么被代理类中的这些接口的方法都会被增强,如果不是这些接口的方法,就不会被增强

第三个参数 用于定义具体的增强方式,传入 InvocationHandler 接口的实现类,因为 InvocationHandler 是函数式接口,因此上面的代码使用了Lambda表达式进行实现

这是 InvocationHandler 接口中唯一的方法 invoke ,也是我们需要实现的方法

public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;

方法中有三个参数

  • proxy是代理对象自己
  • method是当前要增强的方法
  • args是方法需要的参数

在增强方法中进行了 System.out.println("proxy before...");System.out.println("proxy after..."); 增强

而原本的逻辑我们使用反射进行 method.invoke(target, args)

JDK 动态代理原理及仿写

关于这部分的内容我额外整理了另外一篇博客,地址:(占位)

你可能感兴趣的:(Java基础,java,开发语言)