当前位置:首页 > Java

如何代理java

2026-03-19 18:52:05Java

代理模式的基本概念

代理模式是一种设计模式,通过创建一个代理对象来控制对真实对象的访问。代理对象可以在调用真实对象的方法前后添加额外逻辑,例如权限检查、日志记录或延迟加载。

如何代理java

静态代理实现

静态代理需要手动创建代理类,代理类和目标类实现相同的接口。

如何代理java

// 定义接口
public interface Subject {
    void request();
}

// 真实对象
public class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject handles the request.");
    }
}

// 代理类
public class ProxySubject implements Subject {
    private RealSubject realSubject;

    @Override
    public void request() {
        if (realSubject == null) {
            realSubject = new RealSubject();
        }
        System.out.println("Proxy handles pre-processing.");
        realSubject.request();
        System.out.println("Proxy handles post-processing.");
    }
}

// 使用代理
public class Client {
    public static void main(String[] args) {
        Subject proxy = new ProxySubject();
        proxy.request();
    }
}

动态代理实现

动态代理通过反射机制在运行时生成代理对象,无需手动编写代理类。Java提供了java.lang.reflect.ProxyInvocationHandler实现动态代理。

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

// 定义接口
public interface Subject {
    void request();
}

// 真实对象
public class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("RealSubject handles the request.");
    }
}

// 实现InvocationHandler
public 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("DynamicProxy pre-processing.");
        Object result = method.invoke(target, args);
        System.out.println("DynamicProxy post-processing.");
        return result;
    }
}

// 使用动态代理
public class Client {
    public static void main(String[] args) {
        RealSubject realSubject = new RealSubject();
        Subject proxy = (Subject) Proxy.newProxyInstance(
            realSubject.getClass().getClassLoader(),
            realSubject.getClass().getInterfaces(),
            new DynamicProxyHandler(realSubject)
        );
        proxy.request();
    }
}

CGLIB动态代理

对于没有实现接口的类,可以使用CGLIB库实现动态代理。CGLIB通过继承目标类生成子类来实现代理。

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

// 目标类(无需实现接口)
public class RealSubject {
    public void request() {
        System.out.println("RealSubject handles the request.");
    }
}

// 实现MethodInterceptor
public class CglibProxyInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("CGLIB pre-processing.");
        Object result = proxy.invokeSuper(obj, args);
        System.out.println("CGLIB post-processing.");
        return result;
    }
}

// 使用CGLIB代理
public class Client {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(RealSubject.class);
        enhancer.setCallback(new CglibProxyInterceptor());
        RealSubject proxy = (RealSubject) enhancer.create();
        proxy.request();
    }
}

代理模式的应用场景

  • 远程代理:控制对远程对象的访问(如RPC调用)。
  • 虚拟代理:延迟加载资源密集型对象(如图片或文件)。
  • 保护代理:控制对敏感对象的访问权限。
  • 日志代理:在方法调用前后记录日志。

注意事项

  • 动态代理只能代理接口方法,CGLIB可以代理类方法。
  • 动态代理性能略低于静态代理,但灵活性更高。
  • CGLIB通过继承实现代理,因此无法代理final类或方法。

标签: java
分享给朋友:

相关文章

java如何学习

java如何学习

学习Java的有效方法 理解基础概念 Java是一门面向对象的编程语言,掌握基础概念如变量、数据类型、运算符、控制语句(if-else、循环)是必要的。面向对象的核心概念包括类、对象、继承、多态和封装…

java如何输出数组

java如何输出数组

输出数组的方法 在Java中,输出数组内容有多种方式,具体取决于数组类型和输出格式需求。以下是几种常见的方法: 使用Arrays.toString()方法 适用于一维数组,直接调用Arrays.to…

java如何删除文件

java如何删除文件

删除文件的基本方法 使用 java.io.File 类的 delete() 方法可以删除文件。如果文件存在且删除成功,返回 true;否则返回 false。 import java.io…

java如何创建项目

java如何创建项目

使用IDE创建Java项目(以IntelliJ IDEA为例) 打开IntelliJ IDEA,选择“New Project”。 在左侧菜单中选择“Java”,确保已配置JDK(若无需手动添加)。 勾…

java如何编写接口

java如何编写接口

编写Java接口的基本语法 在Java中,接口通过interface关键字定义,可以包含抽象方法、默认方法、静态方法和常量。 public interface MyInterface {…

vue实现java登录注册

vue实现java登录注册

实现 Vue 与 Java 后端的登录注册功能 前端 Vue 部分 安装必要的依赖(如 axios 用于 HTTP 请求): npm install axios 创建登录表单组件(Login.vue…