全部学科
Python全栈
python
NodeJS全栈
nodejs
小程序首页
📅 2026-05-11 7 分钟 ✍️ juanwangdev

Java代理模式

代理模式为对象提供代理,控制对其访问。

模式定义

意图:为对象提供代理,控制访问或添加功能。

三种代理类型

类型特点实现方式
静态代理手写代理类继承/组合
JDK动态代理基于接口Proxy类
CGLIB代理基于类字节码生成

静态代理

接口定义

Java
public interface UserService {
    void addUser(String name);
    void deleteUser(String name);
}

目标对象

Java
public class UserServiceImpl implements UserService {
    @Override
    public void addUser(String name) {
        System.out.println("添加用户: " + name);
    }

    @Override
    public void deleteUser(String name) {
        System.out.println("删除用户: " + name);
    }
}

静态代理

Java
public class UserServiceProxy implements UserService {
    private UserService target;

    public UserServiceProxy(UserService target) {
        this.target = target;
    }

    @Override
    public void addUser(String name) {
        System.out.println("前置处理:检查权限");
        target.addUser(name);
        System.out.println("后置处理:记录日志");
    }

    @Override
    public void deleteUser(String name) {
        System.out.println("前置处理:检查权限");
        target.deleteUser(name);
        System.out.println("后置处理:记录日志");
    }
}

// 使用
UserService service = new UserServiceProxy(new UserServiceImpl());
service.addUser("张三");

JDK动态代理

Java
public class JdkProxy implements InvocationHandler {
    private Object target;

    public Object bind(Object target) {
        this.target = target;
        return Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            this
        );
    }

    @Override
    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;
    }
}

// 使用
UserService service = (UserService) new JdkProxy()
    .bind(new UserServiceImpl());
service.addUser("张三");

CGLIB代理

Java
public class CglibProxy implements MethodInterceptor {
    public Object getProxy(Class<?> clazz) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args,
                            MethodProxy proxy) throws Throwable {
        System.out.println("前置处理");
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("后置处理");
        return result;
    }
}

// 使用(无需接口)
UserServiceImpl service = (UserServiceImpl) new CglibProxy()
    .getProxy(UserServiceImpl.class);
service.addUser("张三");

JDK代理 vs CGLIB代理

特性JDK代理CGLIB代理
基础接口
限制必须有接口不能代理final类
性能较低较高
Spring默认有接口用JDK无接口用CGLIB

实际应用示例

远程代理

Java
public class RemoteProxy implements Service {
    private String host;
    private int port;

    @Override
    public void execute() {
        // 通过网络调用远程服务
        Socket socket = new Socket(host, port);
        // 发送请求、接收响应...
    }
}

虚拟代理

Java
public class ImageProxy implements Image {
    private RealImage realImage;
    private String filename;

    public ImageProxy(String filename) {
        this.filename = filename;
    }

    @Override
    public void display() {
        if (realImage == null) {
            realImage = new RealImage(filename);  // 延迟加载
        }
        realImage.display();
    }
}

保护代理

Java
public class ProtectionProxy implements Service {
    private RealService realService;
    private User user;

    @Override
    public void operation() {
        if (user.hasPermission()) {
            realService.operation();
        } else {
            throw new SecurityException("无权限");
        }
    }
}

Spring AOP代理

Java
@Aspect
@Component
public class LogAspect {
    @Before("execution(* com.example.service.*.*(..))")
    public void before(JoinPoint joinPoint) {
        System.out.println("方法执行前: " + joinPoint.getSignature());
    }

    @After("execution(* com.example.service.*.*(..))")
    public void after(JoinPoint joinPoint) {
        System.out.println("方法执行后");
    }
}

适用场景

  1. 远程代理(RPC)
  2. 虚拟代理(延迟加载)
  3. 保护代理(权限控制)
  4. 智能代理(添加逻辑)
  5. AOP实现

注意事项

JDK动态代理要求目标类有接口

CGLIB不能代理final类和方法

代理类应保持与目标类相同接口

Spring会根据情况自动选择代理方式

要点总结

  1. 代理模式控制对象访问,可添加额外逻辑
  2. 静态代理手写代理类,不够灵活
  3. JDK动态代理基于接口,Proxy.newProxyInstance()
  4. CGLIB基于类继承,无接口也能代理
  5. Spring AOP是代理模式的典型应用

📝 发现内容有误?点击此处直接编辑

← 上一篇 Java享元模式
下一篇 → Java单例模式
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库