MST

星途 面试题库

面试题:Java静态代理模式与动态代理模式在应用场景上的区别

阐述Java静态代理模式与动态代理模式在应用场景方面的差异,分别举例说明在哪些情况下更适合使用静态代理模式和动态代理模式。
50.4万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

静态代理模式应用场景

  1. 场景描述:在系统中业务逻辑相对固定,代理类和被代理类关系明确且短期内不会发生变化时适用。例如,在一个简单的电商订单处理系统中,订单处理服务 OrderService 有一个 processOrder 方法,需要在执行该方法前后添加日志记录功能。
  2. 代码示例
// 定义订单服务接口
interface OrderService {
    void processOrder();
}

// 订单服务实现类
class OrderServiceImpl implements OrderService {
    @Override
    public void processOrder() {
        System.out.println("处理订单");
    }
}

// 订单服务静态代理类
class OrderServiceProxy implements OrderService {
    private OrderService orderService;

    public OrderServiceProxy(OrderService orderService) {
        this.orderService = orderService;
    }

    @Override
    public void processOrder() {
        System.out.println("记录日志:开始处理订单");
        orderService.processOrder();
        System.out.println("记录日志:订单处理完成");
    }
}
  1. 使用方式
public class Main {
    public static void main(String[] args) {
        OrderService orderService = new OrderServiceImpl();
        OrderServiceProxy proxy = new OrderServiceProxy(orderService);
        proxy.processOrder();
    }
}

动态代理模式应用场景

  1. 场景描述:当系统中有多个不同的服务接口,且都需要添加类似的通用功能(如日志记录、事务管理等),或者在运行时才能确定代理的对象时,动态代理更为合适。例如,在一个大型企业级应用中,有用户服务、商品服务等多个服务接口,都需要统一添加性能监控功能。
  2. 代码示例
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

// 定义服务接口
interface UserService {
    void getUserInfo();
}

// 用户服务实现类
class UserServiceImpl implements UserService {
    @Override
    public void getUserInfo() {
        System.out.println("获取用户信息");
    }
}

// 动态代理处理器
class PerformanceMonitorHandler implements InvocationHandler {
    private Object target;

    public PerformanceMonitorHandler(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = method.invoke(target, args);
        long endTime = System.currentTimeMillis();
        System.out.println("方法 " + method.getName() + " 执行时间:" + (endTime - startTime) + " 毫秒");
        return result;
    }
}

// 动态代理生成代理对象
class ProxyFactory {
    public static Object createProxy(Object target) {
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new PerformanceMonitorHandler(target));
    }
}
  1. 使用方式
public class Main {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        UserService proxy = (UserService) ProxyFactory.createProxy(userService);
        proxy.getUserInfo();
    }
}

总结来说,静态代理适合简单、业务逻辑固定且代理关系明确的场景;动态代理则适用于复杂、需要统一处理多个服务接口通用功能或运行时确定代理对象的场景。