Java 语言 代理模式基础 静态代理与动态代理的区别

Java阿木 发布于 25 天前 3 次阅读


摘要:代理模式是一种常用的设计模式,它为其他对象提供一种代理以控制对这个对象的访问。在Java中,代理模式主要分为静态代理和动态代理两种实现方式。本文将详细介绍这两种代理模式的区别,并通过代码示例展示它们的具体实现。

一、

代理模式是一种结构型设计模式,它允许一个对象代表另一个对象进行操作。代理模式的主要目的是在不改变原有对象的基础上,为对象提供额外的功能,如日志记录、安全检查等。在Java中,代理模式主要分为静态代理和动态代理两种实现方式。

二、静态代理

静态代理是指代理类在编译时就已经确定,代理类和被代理类实现相同的接口。静态代理的优点是实现简单,但缺点是如果需要代理的对象很多,则需要为每个对象创建一个代理类,导致代码量庞大。

下面是一个静态代理的简单示例:

java

// 定义一个接口


interface Subject {


void doSomething();


}

// 实现接口的被代理类


class RealSubject implements Subject {


public void doSomething() {


System.out.println("执行真实操作");


}


}

// 静态代理类


class StaticProxy implements Subject {


private Subject subject;

public StaticProxy(Subject subject) {


this.subject = subject;


}

public void doSomething() {


System.out.println("代理开始执行");


subject.doSomething();


System.out.println("代理结束执行");


}


}

// 测试静态代理


public class StaticProxyTest {


public static void main(String[] args) {


Subject realSubject = new RealSubject();


Subject proxy = new StaticProxy(realSubject);


proxy.doSomething();


}


}


在上面的示例中,`RealSubject` 是被代理类,`StaticProxy` 是静态代理类。`StaticProxyTest` 类中创建了 `RealSubject` 的实例,并通过 `StaticProxy` 进行代理调用。

三、动态代理

动态代理是指代理类在运行时通过反射机制动态创建。动态代理不需要为每个代理对象编写代理类,只需编写一个代理类即可。动态代理的优点是灵活性好,可以代理任何实现了接口的类。

下面是一个动态代理的简单示例:

java

import java.lang.reflect.InvocationHandler;


import java.lang.reflect.Method;


import java.lang.reflect.Proxy;

// 定义一个接口


interface Subject {


void doSomething();


}

// 实现接口的被代理类


class RealSubject implements Subject {


public void doSomething() {


System.out.println("执行真实操作");


}


}

// 动态代理类


class DynamicProxy implements InvocationHandler {


private Object target;

public DynamicProxy(Object target) {


this.target = target;


}

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


System.out.println("代理开始执行");


Object result = method.invoke(target, args);


System.out.println("代理结束执行");


return result;


}


}

// 测试动态代理


public class DynamicProxyTest {


public static void main(String[] args) {


Subject realSubject = new RealSubject();


Subject proxy = (Subject) Proxy.newProxyInstance(


Subject.class.getClassLoader(),


new Class[]{Subject.class},


new DynamicProxy(realSubject)


);


proxy.doSomething();


}


}


在上面的示例中,`RealSubject` 是被代理类,`DynamicProxy` 是动态代理类,实现了 `InvocationHandler` 接口。`DynamicProxyTest` 类中创建了 `RealSubject` 的实例,并通过 `Proxy.newProxyInstance` 方法创建了一个动态代理对象。

四、静态代理与动态代理的区别

1. 编写方式:静态代理在编译时就已经确定,代理类和被代理类实现相同的接口;动态代理在运行时通过反射机制动态创建代理类。

2. 灵活性:静态代理灵活性较差,需要为每个代理对象编写代理类;动态代理灵活性较好,可以代理任何实现了接口的类。

3. 代码量:静态代理代码量较大,需要为每个代理对象编写代理类;动态代理代码量较小,只需编写一个代理类。

4. 性能:静态代理性能较好,因为代理类在编译时就已经确定;动态代理性能较差,因为代理类在运行时通过反射机制动态创建。

五、总结

本文介绍了Java代理模式中的静态代理和动态代理两种实现方式,并分析了它们的区别。静态代理实现简单,但灵活性较差;动态代理灵活性较好,但性能较差。在实际开发中,应根据具体需求选择合适的代理模式。