自己完成一个jdk动态代理

本文详细介绍了一种自定义Java代理机制的实现方法,包括自定义类加载器、InvocationHandler接口、代理对象生成类及测试过程。通过动态生成源代码、编译并加载到JVM中,实现了对目标对象的方法调用进行拦截。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

1、自定义类加载器
 

package proxy.custom;

import java.io.*;

public class GPClassLoader extends ClassLoader {
    private File classPathFile;

    public GPClassLoader() {
        String classPath = GPClassLoader.class.getResource("").getPath();
        this.classPathFile = new File(classPath);
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        String className = GPClassLoader.class.getPackage().getName() + "." + name;
        if (classPathFile != null) {
            File classFile = new File(classPathFile, name.replaceAll("\\.", "/")+".class");
            System.out.println(classFile);
            if (classFile.exists()) {
                FileInputStream in = null;
                ByteArrayOutputStream out = null;

                try {
                    in = new FileInputStream(classFile);
                    out = new ByteArrayOutputStream();
                    byte[] buf = new byte[1024];
                    int len;
                    while ((len = in.read(buf)) != -1) {
                        out.write(buf, 0, len);
                    }
                    return defineClass(className, out.toByteArray(), 0, out.size());
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (in != null) {
                        try {
                            in.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (out != null) {
                        try {
                            out.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
        return null;
    }
}

2、自定义InvocationHandler
 

package proxy.custom;

import java.lang.reflect.Method;

public interface GPInvocationHandler {
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}

3、自定义代理对象生成类GPProxy
 

package proxy.custom;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class GPProxy {
    public static  String ln="\r\n";
    public static Object newProxyInstance(GPClassLoader classLoader,Class<?>[] interfaces,GPInvocationHandler h){
        //动态生成源代码,java文件
        String str=generateSrc(interfaces);
        //java文件输出到磁盘
        String filePath=GPProxy.class.getResource("").getPath();
        System.out.println("filePath:"+filePath);
        File f=new File(filePath+"$Proxy0.java");
        FileWriter fw= null;
        try {
            fw = new FileWriter(f);
            fw.write(str);
            fw.flush();
            fw.close();
        //编译成.class文件
        JavaCompiler compiler=ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager manage=compiler.getStandardFileManager(null,null,null);
        Iterable iterable=manage.getJavaFileObjects(f);
        JavaCompiler.CompilationTask task = compiler.getTask(null,manage,null,null,null,iterable);
        task.call();
        manage.close();
        f.delete();
        //编译生成的.class文件加载到JVM中
        Class proxyClass=classLoader.findClass("$Proxy0");
        Constructor constructor=proxyClass.getConstructor(GPInvocationHandler.class);
        //返回字节码重组以后的新的代理对象
        return constructor.newInstance(h);
        } catch (IOException e) {
            e.printStackTrace();
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }catch (Exception e){
            e.printStackTrace();
        }





        return null;
    };

    private static String generateSrc(Class<?>[] interfaces){
        StringBuffer sb=new StringBuffer();
        sb.append("package proxy.custom;"+ln);
        sb.append("import proxy.Person;"+ln);
        sb.append("import java.lang.reflect.Method;");
        sb.append("public class $Proxy0 implements "+interfaces[0].getName()+"{"+ln);
        sb.append("GPInvocationHandler h;");
        sb.append("public $Proxy0(GPInvocationHandler h){"+ln);
        sb.append("this.h=h;");
        sb.append("}");

        for (Method m:interfaces[0].getMethods()
             ) {
            sb.append("public "+m.getReturnType().getName()+" "+m.getName()+"(){"+ln);
            sb.append("try{"+ln);
            sb.append("Method m = "+interfaces[0].getName()+".class.getMethod(\""+m.getName()+"\",new Class[]{});"+ln);
            sb.append("this.h.invoke(this,m,null);"+ln);
            sb.append("}catch (Throwable e){"+ln);
            sb.append("e.printStackTrace();"+ln);
            sb.append("}"+ln);
            sb.append("}"+ln);
        }
        sb.append("}"+ln);

        return sb.toString();
    }

}

4、代理生成类CustomProxy
 

package proxy.custom;

import proxy.Person;

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

public class CustomProxy implements GPInvocationHandler
    {
        //被代理的对象
        private Person target;

        public Object getProxy(Person target){
        this.target=target;
        Class<?> clazz=target.getClass();
        //生成代理对象
        return GPProxy.newProxyInstance(new GPClassLoader(),clazz.getInterfaces(),this);
    }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("这里是珍爱网,已拿到你的要求,帮你寻找真爱");
        method.invoke(this.target,args);
        System.out.println("有情人终成眷属");
        return null;
    }
}

5、测试:

package proxy.custom;

import proxy.Person;
import proxy.jdk.JDKProxy;
import proxy.jdk.XiaoMing;

public class CustomProxyTest {
    public static void main(String[] args) {
        Person xiaoming =new XiaoMing();
        Person person=(Person) new CustomProxy().getProxy(xiaoming);
        System.out.println(person.getClass());
        person.findLove();

    }
}


<think>我们将使用Java的JDK动态代理来创建一个案例。动态代理是Java反射机制的一部分,它允许在运行时创建代理类和对象,主要用于对方法调用进行拦截和处理。 动态代理主要涉及两个类: 1. `java.lang.reflect.Proxy`:用于创建代理对象。 2. `java.lang.reflect.InvocationHandler`:代理对象的调用处理程序接口,我们实现这个接口来定义代理逻辑。 步骤: 1. 定义一个接口(Subject)。 2. 定义一个真实对象(RealSubject)实现这个接口。 3. 定义一个调用处理器(InvocationHandler)实现InvocationHandler接口,在invoke方法中编写代理逻辑。 4. 使用Proxy.newProxyInstance()方法创建代理对象。 5. 通过代理对象调用方法。 案例:我们创建一个简单的接口,包含一个方法。然后创建真实对象和代理对象,代理对象在调用真实对象方法前后打印日志。 注意:JDK动态代理只能代理接口,不能代理没有接口的类。</think>以下是一个使用Java JDK动态代理的完整示例,包含详细注释: ```java import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; // 1. 定义业务接口 interface UserService { void addUser(String username); void deleteUser(String username); } // 2. 实现接口的真实对象 class UserServiceImpl implements UserService { @Override public void addUser(String username) { System.out.println("添加用户: " + username); } @Override public void deleteUser(String username) { System.out.println("删除用户: " + username); } } // 3. 实现InvocationHandler(代理逻辑) class LoggingHandler implements InvocationHandler { private final Object target; // 被代理的真实对象 public LoggingHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 前置增强 System.out.println("[日志] 开始执行: " + method.getName() + "()"); // 调用真实对象的方法 Object result = method.invoke(target, args); // 后置增强 System.out.println("[日志] 执行完成: " + method.getName() + "()\n"); return result; } } public class DynamicProxyDemo { public static void main(String[] args) { // 4. 创建真实对象 UserService realService = new UserServiceImpl(); // 5. 创建调用处理器(传入真实对象) InvocationHandler handler = new LoggingHandler(realService); // 6. 创建代理对象 UserService proxy = (UserService) Proxy.newProxyInstance( UserService.class.getClassLoader(), // 类加载器 new Class[]{UserService.class}, // 代理接口数组 handler // 调用处理器 ); // 7. 通过代理对象调用方法 proxy.addUser("张三"); proxy.deleteUser("李四"); // 打印代理类信息 System.out.println("代理类: " + proxy.getClass().getName()); System.out.println("代理类的父类: " + proxy.getClass().getSuperclass().getName()); System.out.println("代理实现的接口: "); for (Class<?> intf : proxy.getClass().getInterfaces()) { System.out.println(" - " + intf.getName()); } } } ``` ### 代码解释: 1. **接口定义**:`UserService` 声明业务方法 2. **真实对象**:`UserServiceImpl` 实现业务逻辑 3. **调用处理器**: - `LoggingHandler` 实现 `InvocationHandler` - `invoke()` 方法中添加日志增强逻辑 - 通过反射调用真实对象方法 `method.invoke(target, args)` 4. **代理创建**: - `Proxy.newProxyInstance()` 动态生成代理类 - 参数:类加载器、接口数组、调用处理器 5. **运行效果**: - 调用代理方法时自动添加日志 - 输出代理类的结构信息 ### 输出示例: ``` [日志] 开始执行: addUser() 添加用户: 张三 [日志] 执行完成: addUser() [日志] 开始执行: deleteUser() 删除用户: 李四 [日志] 执行完成: deleteUser() 代理类: com.sun.proxy.$Proxy0 代理类的父类: java.lang.reflect.Proxy 代理实现的接口: - UserService ``` ### JDK动态代理原理: 1. **运行时生成代理类**:JVM在内存中动态生成代理类字节码 2. **继承关系**:代理类继承自`java.lang.reflect.Proxy` 3. **方法调用流程**: ```mermaid graph LR A[客户端调用代理方法] --> B[代理类] B --> C[InvocationHandler.invoke] C --> D[执行增强逻辑] D --> E[调用真实对象方法] ``` 4. **限制**:只能代理接口方法(因为Java不支持多继承)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值