Java代理模式

1. 什么是代理模式

代理模式(Proxy Pattern)是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。代理对象在客户端和目标对象之间起到中介作用。

2. 代理模式的核心概念

2.1 主要角色

  • Subject(抽象主题):定义了真实主题和代理主题的共同接口
  • RealSubject(真实主题):实现了抽象主题接口的具体类
  • Proxy(代理):持有真实主题的引用,实现抽象主题接口

2.2 工作原理

Client -> Proxy -> RealSubject

3. Java中代理模式的实现方式

3.1 静态代理

静态代理在编译时就确定了代理关系。

// 抽象主题接口
interface UserService {
    void login(String username, String password);
    void logout(String username);
}

// 真实主题
class UserServiceImpl implements UserService {
    @Override
    public void login(String username, String password) {
        System.out.println("用户 " + username + " 登录成功");
    }
    
    @Override
    public void logout(String username) {
        System.out.println("用户 " + username + " 退出登录");
    }
}

// 静态代理类
class UserServiceProxy implements UserService {
    private UserService userService;
    
    public UserServiceProxy(UserService userService) {
        this.userService = userService;
    }
    
    @Override
    public void login(String username, String password) {
        // 前置处理
        System.out.println("记录登录日志:" + username);
        long startTime = System.currentTimeMillis();
        
        // 调用真实对象
        userService.login(username, password);
        
        // 后置处理
        long endTime = System.currentTimeMillis();
        System.out.println("登录耗时:" + (endTime - startTime) + "ms");
    }
    
    @Override
    public void logout(String username) {
        System.out.println("记录退出日志:" + username);
        userService.logout(username);
    }
}

3.2 JDK动态代理

JDK动态代理基于接口实现,使用反射机制在运行时创建代理对象。

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

// InvocationHandler实现类
class DynamicProxyHandler implements InvocationHandler {
    private Object target;
    
    public DynamicProxyHandler(Object target) {
        this.target = target;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 前置处理
        System.out.println("执行方法前:" + method.getName());
        long startTime = System.currentTimeMillis();
        
        // 执行目标方法
        Object result = method.invoke(target, args);
        
        // 后置处理
        long endTime = System.currentTimeMillis();
        System.out.println("执行方法后:" + method.getName() + ",耗时:" + (endTime - startTime) + "ms");
        
        return result;
    }
}

// 代理工厂
class ProxyFactory {
    public static Object createProxy(Object target) {
        return Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            new DynamicProxyHandler(target)
        );
    }
}

// 使用示例
public class DynamicProxyDemo {
    public static void main(String[] args) {
        UserService userService = new UserServiceImpl();
        UserService proxy = (UserService) ProxyFactory.createProxy(userService);
        
        proxy.login("张三", "123456");
        proxy.logout("张三");
    }
}

3.3 CGLIB动态代理

CGLIB可以为没有接口的类创建代理,通过继承目标类实现。

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;

// 目标类(无需实现接口)
class OrderService {
    public void createOrder(String orderId) {
        System.out.println("创建订单:" + orderId);
    }
    
    public void cancelOrder(String orderId) {
        System.out.println("取消订单:" + orderId);
    }
}

// CGLIB方法拦截器
class CglibMethodInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("CGLIB代理前置处理:" + method.getName());
        
        // 调用父类方法
        Object result = proxy.invokeSuper(obj, args);
        
        System.out.println("CGLIB代理后置处理:" + method.getName());
        return result;
    }
}

// CGLIB代理工厂
class CglibProxyFactory {
    public static Object createProxy(Class<?> clazz) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(new CglibMethodInterceptor());
        return enhancer.create();
    }
}

// 使用示例
public class CglibProxyDemo {
    public static void main(String[] args) {
        OrderService proxy = (OrderService) CglibProxyFactory.createProxy(OrderService.class);
        proxy.createOrder("ORDER001");
        proxy.cancelOrder("ORDER001");
    }
}

4. 代理模式的应用场景

4.1 远程代理

// 模拟远程服务调用
class RemoteServiceProxy implements UserService {
    private String serverUrl;
    
    public RemoteServiceProxy(String serverUrl) {
        this.serverUrl = serverUrl;
    }
    
    @Override
    public void login(String username, String password) {
        System.out.println("连接远程服务器:" + serverUrl);
        // 模拟网络调用
        try {
            Thread.sleep(100);
            System.out.println("远程登录成功:" + username);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    @Override
    public void logout(String username) {
        System.out.println("远程退出登录:" + username);
    }
}

4.2 缓存代理

import java.util.HashMap;
import java.util.Map;

class CacheProxy implements UserService {
    private UserService userService;
    private Map<String, Object> cache = new HashMap<>();
    
    public CacheProxy(UserService userService) {
        this.userService = userService;
    }
    
    @Override
    public void login(String username, String password) {
        String key = "login_" + username;
        if (cache.containsKey(key)) {
            System.out.println("从缓存获取登录信息:" + username);
            return;
        }
         userService.login(username, password);
        cache.put(key, "logged_in");
        System.out.println("登录信息已缓存");
    }
    
    @Override
    public void logout(String username) {
        String key = "login_" + username;
        cache.remove(key);
        userService.logout(username);
        System.out.println("清除缓存:" + username);
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值