代理模式之JDK动态代理 — “JDK Dynamic Proxy“

动态代理的原理是什么?

所谓的动态代理,他是一个代理机制,代理机制能够看做是对调用目标的一个包装,这样咱们对目标代码的调用不是直接发生的,而是经过代理完成,经过代理能够有效的让调用者和实现者之间解耦,常见的代理模式包括:JDK Proxy、cglib。java

JDK动态代理

下面能够看看JDK动态代理的一个简单的例子,下面只是加了一句print,在生产系统中,咱们能够轻松扩展相似逻辑进行诊断、限流等。ide

  • 接口Hello
public interface Hello{
    void sayHello();
}
  • 接口的实现类HelloImpl
public class HelloImpl implements Hello {

    @Override
    public void sayHello() {
        System.out.println("Hello JDK Dynamic Proxy!!!");
    }
}
  • DynamicProxyMain类
public class DynamicProxyMain {

    public static void main(String[] args) {
        HelloImpl hello = new HelloImpl();
        JDKDynamicProxy handler = new JDKDynamicProxy(hello);

        //构造代码实例
        Hello proxyHello = new JDKDynamicProxy(new HelloImpl()).getProxy();
        //使用代理对象调用代理方法
        proxyHello.sayHello();
    }

    /**
     * 建立一个代理类JDKDynamicProxy实现java.lang.reflect.InvocationHandler接口,重写invoke方法
     */
    static class JDKDynamicProxy implements InvocationHandler{

        private Object target;
        public JDKDynamicProxy(Object target) {
            this.target = target;
        }

        /**
         * 获取被代理接口实例对象
         * @param <T>
         * @return
         */
        public <T> T getProxy() {
            return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("正在代理sayHello方法......");
            Object result = method.invoke(target, args);
            return result;
        }
    }
}

运行main函数,结果以下:函数

正在代理sayHello方法......
Hello JDK Dynamic Proxy!!!
  • 上面的JDK Proxy例子,很是简单地实现了动态代理的构建和代理操做。首先,咱们自定义对应的 JDKDynamicProxy ;而后,以接口Hello为纽带,为被调用目标建立代理对象,进而应用程序就可使用代理对象间接运行调用目标的逻辑,代理为应用插入额外逻辑(这里仅仅提供println方法)提供了入口。
  • 不过,JDK动态代理也有必定局限性,由于必须是以接口为中心,至关于添 加了一种对于被调用者没有太大意义的限制。咱们实例化的是 Proxy 对象,而不是真正的 被调用类型,这在实践中仍是可能带来各类不便和能力退化。
  • 若是被调用者每个月实现接口,而咱们有但愿使用动态代理机制,那么就能够考虑使用其余的方式,好比:Spring AOP支持两种模式的动态代理,JDK Proxy和cglib,选择cglib能够克服对接口的依赖。
相关文章
相关标签/搜索