美文网首页JavaJava
Java中的静态代理和动态代理

Java中的静态代理和动态代理

作者: zhong0316 | 来源:发表于2019-02-21 18:24 被阅读1次

什么是代理

代理是设计模式的一种,代理类为委托类提供消息预处理,消息转发,事后消息处理等功能。Java中的代理分为三种角色:

  1. 代理类(ProxySubject)
  2. 委托类(RealSubject)
  3. 接口(Subject)

三者关系可以表示如下图:

代理模式

Java中的代理按照代理类生成时机不同又分为静态代理和动态代理。静态代理代理类在编译期就生成,而动态代理代理类则是在Java运行时动态生成。

静态代理

Java中的静态代理要求代理类(ProxySubject)和委托类(RealSubject)都实现同一个接口(Subject)。静态代理中代理类在编译期就已经确定,而动态代理则是JVM运行时动态生成,静态代理的效率相对动态代理来说相对高一些,但是静态代理代码冗余大,一单需要修改接口,代理类和委托类都需要修改。
举个例子:

接口(Subject)

interface HelloService {
    void sayHello();
}

委托类

class HelloServiceImpl implements HelloService {
    @Override
    public void sayHello() {
        System.out.println("Hello World!");
    }
}

代理类

class HelloServiceProxy implements HelloService {
    private HelloService helloService;
    
    public HelloServiceProxy(HelloService helloService) {
        this.helloService = helloService;
    }
    
    @Override
    public void sayHello() {
        System.out.println("Before say hello...");
        helloService.sayHello();
        System.out.println("After say hello...");
    }
}

测试类

public class HelloServiceProxyTest {
    
    public static void main(String[] args) {
        HelloService helloService = new HelloServiceImpl();
        HelloServiceProxy proxy = new HelloServiceProxy(helloService);
        proxy.sayHello();
    }
}

输出结果

Before say hello...
Hello World!
After say hello...

动态代理

Java中的动态代理依靠反射来实现,代理类和委托类不需要实现同一个接口。委托类需要实现接口,否则无法创建动态代理。代理类在JVM运行时动态生成,而不是编译期就能确定。
Java动态代理主要涉及到两个类:java.lang.reflect.Proxyjava.lang.reflect.InvocationHandler。代理类需要实现InvocationHandler接口或者创建匿名内部类,而Proxy用于创建动态动态。
我们用动态代理来实现HelloService:

接口(Subject)

interface HelloService {
    void sayHello();
}

委托类

class HelloServiceImpl implements HelloService {
    @Override
    public void sayHello() {
        System.out.println("Hello World!");
    }
}

动态代理类

class HelloServiceDynamicProxy {

    private HelloService helloService;
    public HelloServiceDynamicProxy(HelloService helloService) {
        this.helloService = helloService;
    }

    public Object getProxyInstance() {
        return Proxy.newProxyInstance(helloService.getClass().getClassLoader(), helloService.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("Before say hello...");
                Object ret = method.invoke(helloService, args);
                System.out.println("After say hello...");
                return ret;
            }
        });
    }
}

测试类

public class HelloServieDynamicProxyTest {
    public static void main(String[] args){
        HelloService helloService = new HelloServiceImpl();
        HelloService dynamicProxy = (HelloService) new HelloServiceDynamicProxy(helloService).getProxyInstance();
        dynamicProxy.sayHello();
    }
}

输出结果

Before say hello...
Hello World!
After say hello...

总结

  1. 静态代理实现较简单,代理类在编译期生成,效率高。缺点是会生成大量的代理类。
  2. JDK动态代理不要求代理类和委托类实现同一个接口,但是委托类需要实现接口,代理类需要实现InvocationHandler接口。
  3. 动态代理要求代理类InvocationHandler接口,通过反射代理方法,比较消耗系统性能,但可以减少代理类的数量,使用更灵活。

相关文章

  • 动态代理的两种方式

    静态代理就不说了,基本用到的都是动态代理。 Java中动态代理有JDK动态代理和CGLIB动态代理。 JDK代理的...

  • 编程常用的设计模式

    动态代理和静态代理 静态代理 动态代理 静态代理与动态代理的区别 JDK中的动态代理和CGLIB 实现动态代理的方...

  • java的动态代理详解(javassist,cglib)

    俗话说:Coder不知动态代理,走在路上没人理!!!所以本文尝试说明白java代理模式,代理中的静态代理和动态代理...

  • 浅谈Java和SAP ABAP的静态代理和动态代理,以及ABAP

    文章目录 Java的静态代理 静态代理的优缺点 ABAP的静态代理 Spring AOP的动态代理 JDK动态代理...

  • java反射和动态代理

    java动态代理Proxy.newProxyInstance 详解java代理机制(静态代理、动态代理)以及使用场景

  • Java动态代理从入门到原理再到实战

    目录 前言 什么是动态代理,和静态代理有什么区别 Java动态代理的简单使用 Java动态代理的原理解读 动态代理...

  • Java基础系列-静态代理和动态代理

    原创文章,转载请标注出处:《Java基础系列-静态代理和动态代理》 1、动态代理(Dynamic Proxy) 代...

  • 代理简记

    Java静态代理 委托类和代理类,实现共同接口 共同接口: 委托类: 代理类: 测试结果: Java动态代理 通过...

  • 静态代理、动态代理

    代理分为静态代理和动态代理 按照代理创建的时期,可以分为静态代理和动态代理: (1) 静态代理:由程序员或者...

  • JAVA动态代理的实现方式

    1. 静态代理VS动态代理 代理类可以增强被代理对象的方法。可分为静态代理和动态代理。 1.1 静态代理 静态代理...

网友评论

    本文标题:Java中的静态代理和动态代理

    本文链接:https://www.haomeiwen.com/subject/riudyqtx.html