Java代理模式案例

wen java案例 2

本文目录导读:

Java代理模式案例

  1. 代理模式概述
  2. 完整案例代码
  3. 运行结果
  4. 代理模式的优势和应用场景

我将为您详细介绍Java代理模式的几种实现方式,并给出完整的案例代码。

代理模式概述

代理模式(Proxy Pattern)为其他对象提供一种代理以控制对这个对象的访问,它属于结构型设计模式。

代理模式的主要类型:

  • 静态代理:在编译时确定代理类
  • 动态代理(JDK):基于接口的代理
  • CGLIB代理:基于继承的代理

完整案例代码

1 定义接口和真实主题

// 业务接口
public interface UserService {
    void addUser(String name);
    void deleteUser(String name);
    String getUser(String name);
}
// 真实主题类
public class UserServiceImpl implements UserService {
    @Override
    public void addUser(String name) {
        // 模拟业务处理
        System.out.println("添加用户:" + name);
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void deleteUser(String name) {
        System.out.println("删除用户:" + name);
        try {
            Thread.sleep(300);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    @Override
    public String getUser(String name) {
        System.out.println("查询用户:" + name);
        return name + "的信息";
    }
}

2 静态代理实现

// 静态代理类
public class StaticProxy implements UserService {
    private final UserService target;
    public StaticProxy(UserService target) {
        this.target = target;
    }
    @Override
    public void addUser(String name) {
        System.out.println("【静态代理】-开始执行添加用户操作...");
        long startTime = System.currentTimeMillis();
        // 调用真实对象的方法
        target.addUser(name);
        long endTime = System.currentTimeMillis();
        System.out.println("【静态代理】-添加用户操作完成,耗时:" + (endTime - startTime) + "ms");
    }
    @Override
    public void deleteUser(String name) {
        System.out.println("【静态代理】-开始执行删除用户操作...");
        long startTime = System.currentTimeMillis();
        target.deleteUser(name);
        long endTime = System.currentTimeMillis();
        System.out.println("【静态代理】-删除用户操作完成,耗时:" + (endTime - startTime) + "ms");
    }
    @Override
    public String getUser(String name) {
        System.out.println("【静态代理】-开始执行查询用户操作...");
        long startTime = System.currentTimeMillis();
        String result = target.getUser(name);
        long endTime = System.currentTimeMillis();
        System.out.println("【静态代理】-查询用户操作完成,耗时:" + (endTime - startTime) + "ms");
        return result;
    }
}

3 JDK动态代理

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 动态代理类
public class DynamicProxy implements InvocationHandler {
    private final Object target;
    public DynamicProxy(Object target) {
        this.target = target;
    }
    // 创建代理对象
    public Object createProxy() {
        return Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            this
        );
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        String methodName = method.getName();
        System.out.println("【JDK动态代理】-" + methodName + "方法开始执行...");
        long startTime = System.currentTimeMillis();
        // 执行前置处理
        if (args != null && args.length > 0) {
            System.out.println("【JDK动态代理】-参数:");
            for (Object arg : args) {
                System.out.println("  " + arg);
            }
        }
        // 调用真实对象的方法
        Object result = method.invoke(target, args);
        long endTime = System.currentTimeMillis();
        System.out.println("【JDK动态代理】-" + methodName + "方法执行完成,耗时:" + (endTime - startTime) + "ms");
        return result;
    }
}

4 CGLIB代理

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
// CGLIB代理类
public class CGLIBProxy implements MethodInterceptor {
    private final Object target;
    public CGLIBProxy(Object target) {
        this.target = target;
    }
    // 创建代理对象
    public Object createProxy() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) 
            throws Throwable {
        String methodName = method.getName();
        System.out.println("【CGLIB代理】-" + methodName + "方法开始执行...");
        long startTime = System.currentTimeMillis();
        // 前置处理
        if (args != null && args.length > 0) {
            System.out.println("【CGLIB代理】-参数:" + String.join(", ", 
                java.util.Arrays.stream(args).map(String::valueOf).toArray(String[]::new)));
        }
        // 调用真实对象的方法
        Object result = proxy.invoke(target, args);
        long endTime = System.currentTimeMillis();
        System.out.println("【CGLIB代理】-" + methodName + "方法执行完成,耗时:" + (endTime - startTime) + "ms");
        return result;
    }
}

5 主测试类

public class ProxyPatternDemo {
    public static void main(String[] args) {
        System.out.println("========== 代理模式案例演示 ==========\n");
        // 创建真实对象
        UserService userService = new UserServiceImpl();
        // 1. 静态代理测试
        System.out.println("----- 1. 静态代理 -----");
        UserService staticProxy = new StaticProxy(userService);
        staticProxy.addUser("张三");
        staticProxy.deleteUser("张三");
        System.out.println();
        // 2. JDK动态代理测试
        System.out.println("----- 2. JDK动态代理 -----");
        DynamicProxy dynamicProxyHandler = new DynamicProxy(userService);
        UserService dynamicProxy = (UserService) dynamicProxyHandler.createProxy();
        dynamicProxy.addUser("李四");
        String userInfo = dynamicProxy.getUser("李四");
        System.out.println("查询结果:" + userInfo);
        System.out.println();
        // 3. CGLIB代理测试
        System.out.println("----- 3. CGLIB代理 -----");
        CGLIBProxy cglibProxyHandler = new CGLIBProxy(userService);
        UserServiceImpl cglibProxy = (UserServiceImpl) cglibProxyHandler.createProxy();
        cglibProxy.addUser("王五");
        cglibProxy.deleteUser("王五");
        System.out.println();
        // 4. 对比不同代理方式
        compareProxies();
    }
    private static void compareProxies() {
        System.out.println("----- 代理方式对比 -----");
        System.out.println("1. 静态代理:简单直观,但每个类都需要手动创建代理类,代码重复");
        System.out.println("2. JDK动态代理:基于接口,代码复用性好,但只能代理接口");
        System.out.println("3. CGLIB代理:基于继承,无需接口,但性能略低于JDK代理");
    }
}

6 使用场景扩展(权限控制示例)

// 权限控制的代理示例
public class PermissionProxy implements UserService {
    private final UserService target;
    private String currentUserRole;
    public PermissionProxy(UserService target, String role) {
        this.target = target;
        this.currentUserRole = role;
    }
    @Override
    public void addUser(String name) {
        if ("admin".equals(currentUserRole)) {
            System.out.println("【权限代理】-管理员权限验证通过,执行添加操作");
            target.addUser(name);
        } else {
            System.out.println("【权限代理】-权限不足,无法添加用户(需要管理员权限)");
        }
    }
    @Override
    public void deleteUser(String name) {
        if ("admin".equals(currentUserRole)) {
            System.out.println("【权限代理】-管理员权限验证通过,执行删除操作");
            target.deleteUser(name);
        } else {
            System.out.println("【权限代理】-权限不足,无法删除用户(需要管理员权限)");
        }
    }
    @Override
    public String getUser(String name) {
        // 查询操作所有人都有权限
        System.out.println("【权限代理】-权限验证通过(查询操作对所有用户开放)");
        return target.getUser(name);
    }
}

运行结果

========== 代理模式案例演示 ==========
----- 1. 静态代理 -----
【静态代理】-开始执行添加用户操作...
添加用户:张三
【静态代理】-添加用户操作完成,耗时:500ms
【静态代理】-开始执行删除用户操作...
删除用户:张三
【静态代理】-删除用户操作完成,耗时:300ms
----- 2. JDK动态代理 -----
【JDK动态代理】-addUser方法开始执行...
【JDK动态代理】-参数:
  李四
添加用户:李四
【JDK动态代理】-addUser方法执行完成,耗时:500ms
【JDK动态代理】-getUser方法开始执行...
【JDK动态代理】-参数:
  李四
查询用户:李四
【JDK动态代理】-getUser方法执行完成,耗时:0ms
查询结果:李四的信息
----- 3. CGLIB代理 -----
【CGLIB代理】-addUser方法开始执行...
【CGLIB代理】-参数:王五
添加用户:王五
【CGLIB代理】-addUser方法执行完成,耗时:500ms
【CGLIB代理】-deleteUser方法开始执行...
【CGLIB代理】-参数:王五
删除用户:王五
【CGLIB代理】-deleteUser方法执行完成,耗时:300ms
----- 代理方式对比 -----
1. 静态代理:简单直观,但每个类都需要手动创建代理类,代码重复
2. JDK动态代理:基于接口,代码复用性好,但只能代理接口
3. CGLIB代理:基于继承,无需接口,但性能略低于JDK代理

代理模式的优势和应用场景

优势:

  1. 职责清晰:代理类负责预处理、过滤等操作
  2. 扩展性好:可以在不修改目标类的情况下增加功能
  3. 安全性好:可以控制对目标对象的访问权限

典型应用场景:

  1. Spring AOP:事务管理、日志记录
  2. Spring MVC:拦截器
  3. MyBatis:Mapper接口的动态代理
  4. Hibernate:延迟加载
  5. Java RMI:远程方法调用
  6. 安全控制:权限验证、身份认证

注意事项:

  • 静态代理类需要手动编写,会产生大量冗余代码
  • JDK代理要求目标类必须实现接口
  • CGLIB代理不能代理final类和方法

抱歉,评论功能暂时关闭!