自学内容网 自学内容网

Java:JDK如何创建动态代理Proxy

这几天学spring的源码遇到的,发现自己没用过都,简单学习一下。

介绍:    

        动态代理是Java编程语言中的一种特性,允许在运行时创建代理类和对象。它主要用于实现AOP(面向切面编程)和在运行时处理其他类的方法调用,例如远程方法调用(RPC)、事务管理等。

在Java中,有两种主要的动态代理实现方式:

  1. 基于接口的动态代理:使用Java自带的java.lang.reflect.Proxy类。基于接口的动态代理要求被代理的类必须实现至少一个接口,代理对象会实现相同的接口,并在运行时处理接口方法的调用。该方式是Java标准库提供的,但仅支持基于接口的代理。

  2. 基于类的动态代理:使用第三方库,例如CGLIB(Code Generation Library)。这种方式可以代理那些没有实现接口的类,它通过继承被代理类并重写其方法来创建代理对象。相比于基于接口的动态代理,基于类的动态代理更灵活,但在性能上会有一些开销。

我觉得吧,其实就是对方法的抽取和加强而已。

简单创建:

比如一个明星,唱歌前要收钱,跳舞前要准备场地。

bigStar类:

public class BigStar implements Star{
    private String name;

    public BigStar(String name) {
        this.name = name;
    }
    public String sing(String singName) {
        System.out.println(name + "唱了" +singName);
        return "success";
    }

    public void dance() {
        System.out.println("跳舞了");
    }

}

        就是我们正常的普通的类。

Star接口:

public interface Star {
    public String sing(String singName);
    public void dance();
}

        代理必须通过实现接口,告诉代理对象代理那些方法。

代理的实现类:

public class ProxyUtil {
    public static Star createProxy(BigStar bigStar) {
        // ClassLoader loader, 类加载器,一般都用的当前类的加载器
        // Class<?>[] interfaces,  指定生成的代码有那些方法,可以有多个,用数组接收
        // InvocationHandler h) 匿名对象,指定代理干什么事
        Star startProxy = (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 (method.getName().equals("sing")) {
                            System.out.println("唱歌前收钱");
                        } else if (method.getName().equals("dance")) {
                            System.out.println("跳舞前准备场地");
                        }
                        return method.invoke(bigStar,args);
                    }
                });
        return startProxy;
    }
}

ClassLoader loader, 类加载器,一般都用的当前类的加载器
Class<?>[] interfaces,  指定生成的代码有那些方法,可以有多个,用数组接收
InvocationHandler h) 匿名对象,指定代理干什么事

test:

public class Test {
    public static void main(String[] args) {
        BigStar lpy = new BigStar("lpy");
        Star proxy = ProxyUtil.createProxy(lpy);

        String res = proxy.sing("晴天");
        proxy.dance();

    }
}

运行结果:

原理:

        看一下这个调用过程就懂了,不再多说了。


原文地址:https://blog.csdn.net/Cosmoshhhyyy/article/details/137601663

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!