首页/ 学科题库/ java/ Java代理模式
java 实战教程

Java代理模式

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是代理模式的典型应用
想在手机上练这篇的配套题目?
使用微信 卷王开发者小程序/App,首页顶部扫一扫识别下方二维码,即可解锁本讲对应真题与错题本。
了解产品 App
← 上一篇 Java享元模式 下一篇 → Java责任链模式