美文网首页
java 笔记 - 动态代理(难点)

java 笔记 - 动态代理(难点)

作者: 阿巳交不起水电费 | 来源:发表于2025-05-14 11:33 被阅读0次

什么是动态代理?

动态代理是 Java 提供的一种在运行时动态创建代理类和对象的技术。它允许你在不修改原始类代码的情况下,通过一个代理对象来控制对原始对象的访问。也就是代理可以无侵入式的给对象增强其他的功能。

需要注意的是:是通过接口来保证代理的样子的,后面的对象和代理需要实现同一个接口,接口里面就是需要被代理的所有方法

动态代理的核心组件

java.lang.reflect.Proxy 类 - 用于创建动态代理类和实例
java.lang.reflect.InvocationHandler 接口 - 代理对象的调用处理器


image.png

代码如下:

下面的代码给 BigStar 里面的唱歌跳舞方法增加了功能,完整代码如下:

Star 接口 - 里面是需要被代理的方法

package com.动态代理_基础最终章;

public interface Star {
    // 对象和代理都需要实现这个接口,这个接口里面的方法都需要被代理

    // 唱歌
    public abstract String sing(String name);

    // 跳舞
    public abstract void dance();
}

BigStar 类,这个类实例化的对象需要被代理

package com.动态代理_基础最终章;

public class BigStar implements Star{
    private String name;

    public BigStar() {
    }

    public BigStar(String name) {
        this.name = name;
    }

    // 唱歌
    @Override
    public String sing(String name) {
        System.out.println(this.name + "正在唱" + name);
        return "唱完了,说声谢谢";
    }

    // 跳舞
    @Override
    public void dance(){
        System.out.println(this.name + "在跳舞");
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    public String toString() {
        return "BigStar{name = " + name + "}";
    }
}

ProxyUtil 类 - 用于创建一个代理对象

package com.动态代理_基础最终章;

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

/**
 * 类的作用:
 * 创建一个代理
 */
public class ProxyUtil {
    public static Star createProxy(BigStar bigStar) {

        Star o = (Star) Proxy.newProxyInstance(
                ProxyUtil.class.getClassLoader(), // 参数一:用于指定用哪个类加载器去加载生成的代理类
                new Class[]{Star.class}, // 参数二:指定接口,接口里面是需要代理的方法
                // 参数三:用来指定生成的代理对象要干什么
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                        // 唱歌跳舞方法前要执行的逻辑
                        if("sing".equals(method.getName())) {
                            System.out.println("唱歌前要准备话筒。。。");
                        }else if("dance".equals(method.getName())) {
                            System.out.println("跳舞前要准备场地。。。");
                        }

                        // 执行原始对象里面的方法
                        return method.invoke(bigStar, args);
                    }
                }
        );

        return o;
    }
}

测试类

package com.动态代理_基础最终章;

public class test {
    public static void main(String[] args) {
        // 需要代理的对象
        BigStar bigStar = new BigStar("xx明星");
        // 代理这个对象
        Star proxy = ProxyUtil.createProxy(bigStar);

        // 调用代理的方法 - 唱歌
        String res = proxy.sing("月亮之上");
        System.out.println(res);

        // 调用代理的方法 - 跳舞
        proxy.dance();
    }
}

扩展 - jdk 代理

spring aop 动态代理模式有用的

public class ProxyFactory {

    private Object target;

    public ProxyFactory(Object target) {
        this.target = target;
    }

    public Object getProxy(){

        /**
         * newProxyInstance():创建一个代理实例
         * 其中有三个参数:
         * 1、classLoader:加载动态生成的代理类的类加载器
         * 2、interfaces:目标对象实现的所有接口的class对象所组成的数组
         * 3、invocationHandler:设置代理对象实现目标对象方法的过程,即代理类中如何重写接口中的抽象方法
         */
        ClassLoader classLoader = target.getClass().getClassLoader();
        Class<?>[] interfaces = target.getClass().getInterfaces();
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                /**
                 * proxy:代理对象
                 * method:代理对象需要实现的方法,即其中需要重写的方法
                 * args:method所对应方法的参数
                 */
                Object result = null;
                try {
                    System.out.println("[动态代理][日志] "+method.getName()+",参数:"+ Arrays.toString(args));
                    result = method.invoke(target, args);
                    System.out.println("[动态代理][日志] "+method.getName()+",结果:"+ result);
                } catch (Exception e) {
                    e.printStackTrace();
                    System.out.println("[动态代理][日志] "+method.getName()+",异常:"+e.getMessage());
                } finally {
                    System.out.println("[动态代理][日志] "+method.getName()+",方法执行完毕");
                }
                return result;
            }
        };

        return Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
    }
}

测试类

@Test
public void testDynamicProxy(){
    ProxyFactory factory = new ProxyFactory(new CalculatorLogImpl());
    Calculator proxy = (Calculator) factory.getProxy();
    proxy.div(1,0);
    //proxy.div(1,1);
}

参考:
黑马java教程
尚硅谷新版SSM框架教程

相关文章

  • java基础巩固笔记(4)-代理

    标签: java Contents java基础巩固笔记(4)-代理概念动态代理创建动态类动态代理的工作原理面向切...

  • 2021校招 复习总结

    笔记导航: JAVA: 泛型 反射和动态代理 注解 JAVA多线程 ReentrantLock,Volatile,...

  • Proxy代理者模式(一)

    摘要 本篇笔记针对Java设计模式中最难理解的代理者模式进行讲解,从静态代理、动态代理,及Java相关代理类的应用...

  • Java 动态代理

    java的动态代理机制详解 JDK动态代理详解 Java核心技术点之动态代理

  • JDK动态代理详解

    JDK动态代理详解 java动态代理类 Java动态代理类位于java.lang.reflect包下,一般主要涉及...

  • Java动态代理从入门到原理再到实战

    目录 前言 什么是动态代理,和静态代理有什么区别 Java动态代理的简单使用 Java动态代理的原理解读 动态代理...

  • java反射和动态代理

    java动态代理Proxy.newProxyInstance 详解java代理机制(静态代理、动态代理)以及使用场景

  • 保存java 动态代理生成的字节码文件

    保存java 动态代理生成的字节码文件 在Java中,常用的动态代理技术有JDK的动态代理和cglib动态代理,不...

  • java动态代理(JDK和cglib)(转载自http://ww

    java动态代理(JDK和cglib) JAVA的动态代理 代理模式 代理模式是常用的java设计模式,他的特征是...

  • java 动态代理

    动态代理动态代理可以让我们在运行时动态生成代理类,解耦程度更高。Java 动态代理的实现主要借助于 java.la...

网友评论

      本文标题:java 笔记 - 动态代理(难点)

      本文链接:https://www.haomeiwen.com/subject/fsdbijtx.html