java动态代理和静态代理的区别

原创admin 分类:热门问答 0

java动态代理和静态代理的区别

在Java编程的世界里,代理模式是一种结构型设计模式,它允许我们通过一个代理对象来间接访问另一个对象。这种模式在很多框架中都有应用,比如Spring的AOP。代理模式主要分为两种:静态代理和动态代理。在本文中,我将详细解释这两种代理的区别,并提供代码案例以便更好地理解。

代理模式的核心概念

定义与目的

代理模式的目的是为其他对象提供一个代理以控制对这个对象的访问。这样,我们可以在不修改目标对象的前提下扩展目标对象的功能,或对目标对象的访问进行控制。【1】

条件

  • 目标对象:需要被代理的原始对象。
  • 代理对象:在客户端和目标对象之间起到中介的作用。
  • 客户端:使用代理对象而不是直接使用目标对象的代码。【1】

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

静态代理

静态代理是在编译时就已经确定代理类和目标类的关系,代理类需要显式地实现目标接口。【2】

核心类与方法

  • 代理类:需要手动编写,实现目标接口。
  • 目标类:被代理的类,实现具体的业务逻辑。【2】

使用场景

静态代理适用于接口数量较少、目标对象固定的情况,或者在编译时就已经确定代理行为的场景。【2】

代码案例

// 目标接口
public interface Animal {
    void action();
    void breath();
}

// 被代理类
public class Cat implements Animal {
    @Override
    public void action() {
        System.out.println("Cat action");
    }

    @Override
    public void breath() {
        System.out.println("Cat breath");
    }
}

// 代理类
public class CatProxy implements Animal {
    private Cat cat;

    public CatProxy(Cat cat) {
        this.cat = cat;
    }

    @Override
    public void action() {
        System.out.println("Before Cat action");
        cat.action();
        System.out.println("After Cat action");
    }

    @Override
    public void breath() {
        System.out.println("Before Cat breath");
        cat.breath();
        System.out.println("After Cat breath");
    }
}

// 客户端使用
public class Client {
    public static void main(String[] args) {
        Cat cat = new Cat();
        CatProxy catProxy = new CatProxy(cat);
        catProxy.action();
        catProxy.breath();
    }
}

动态代理

动态代理是在运行时动态生成代理类,不需要手动编写代理类。【2】

核心类与方法

  • java.lang.reflect.Proxy:用来创建代理类的类。
  • java.lang.reflect.InvocationHandler:用来处理代理对象的方法调用。【2】

使用场景

动态代理适用于接口多、目标对象不确定或在运行时才能确定的情况。它常用于框架中实现AOP(面向切面编程)。【4】

代码案例

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 目标接口
public interface Animal {
    void action();
    void breath();
}

// 被代理类
public class Cat implements Animal {
    @Override
    public void action() {
        System.out.println("Cat action");
    }

    @Override
    public void breath() {
        System.out.println("Cat breath");
    }
}

// 动态代理处理器
public class CatInvocationHandler implements InvocationHandler {
    private Object cat;

    public CatInvocationHandler(Object cat) {
        this.cat = cat;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before method invocation");
        Object result = method.invoke(cat, args);
        System.out.println("After method invocation");
        return result;
    }
}

// 客户端使用
public class Client {
    public static void main(String[] args) {
        Cat cat = new Cat();
        CatInvocationHandler handler = new CatInvocationHandler(cat);
        Animal proxy = (Animal) Proxy.newProxyInstance(
                Cat.class.getClassLoader(),
                new Class[]{Animal.class},
                handler
        );
        proxy.action();
        proxy.breath();
    }
}

对比表格

特性 静态代理 动态代理
代理类生成时间 编译时 运行时
代理类编写方式 手动编写 动态生成
适用场景 接口数量较少,目标对象固定 接口多,目标对象不确定
灵活性 较低 较高
性能 较高 较低
目标对象要求 必须实现接口 可以不实现接口(使用CGLIB)

总结

通过本文的讲解,我们了解了Java中的静态代理和动态代理的定义、核心类与方法、使用场景以及代码案例。静态代理适合于编译时已知代理行为的情况,而动态代理则适用于运行时动态生成代理类的场景。在实际开发中,我们可以根据具体需求选择合适的代理方式来实现功能。

相关文章

猜你喜欢

领取相关Java架构师视频资料

网络安全学习平台视频资料