注:示例代码如下
public interface ProxyInterface {
String targetMethod(String param); }
讯享网
讯享网public class JDKProxy {
public Object getInstanceProxy(Class c) {
Object instance = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{
c}, (proxy, method, args) -> {
System.out.println("代理被执行。。。。"); System.out.println("执行完毕"); if (args != null) {
System.out.println("参数:" + args[0]); } return "您好"; }); return instance; } }
public class ProxyInterfaceMain {
public static void main(String[] args) {
JDKProxy jdkProxy = new JDKProxy(); ProxyInterface instanceProxy = (ProxyInterface) jdkProxy.getInstanceProxy(ProxyInterface.class); System.out.println(instanceProxy.targetMethod("你好")); // System.out.println(instanceProxy); } }
JDK的动态代理可以通过Proxy类型newProxyInstance()方法实现,方法有三个参数
讯享网 public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
JDK的动态代理生成,只能为接口提供,也就是说,有以下两种情况
1、接口没有实现类
如果接口没有实现类,那么生成的代理对象,在invoke方法中,则不能调用method.invoke方法,因为接口没有实现,调用这个方法传入proxy则会死循环,传入接口的类型,将会报错,则,接口所有的方法,都只能走InvocationHandler的invoke方法逻辑
而且,如果没有实现类,在调用Proxy.newProxyInstance时,要注意传入的interfaces参数,没有实现类,则需要用new Class[]{ProxyInterface.class}的方法传入,这样就可以生成代理了,如果传的是new Class[0],那么默认只会给toString方法代理,具体在下面有说明
2、
如果接口有实现类,那么在调用Proxy.newProxyInstance时,就需要用实现的Class对象,调用getInterface()方法,得到这个类实现的接口数组,然后这样代理对象才能对实现类的所有接口进行代理。

讯享网

- ClassLoader loader
类加载器,一般都是直接获取当前线程的类加载器,也可以传入自定义的
获取当前线程类加载器:
Thread.currentThread().getContextClassLoader()
为什么要传入ClassLoader(类加载器、CL)?
JVM通过类加载器来将.class文件加载到Meta space(元空间)中,也就是会通过类加载器,创建一个类的Class对象
而JDK的动态代理,是一种动态字节码技术,通过在JVM中直接写入字节码的方式,为原始类创建一个代理类。
再结合前面说的,如果要为这个代理类创建一个代理对象,则需要通过类加载器将代理类加载(创建一个代理类的Class对象)
而由于代理类是动态生成的,所以没有对应的类加载器,则只能通过方法参数传递进来(借用一个类加载器)。
- Class<?>[] interfaces
需要代理的接口,这个参数有点特殊,它可以传入需要代理的接口的class,也可以传入接口中的方法的class
1、传入接口的class

那么代理则会生成这个接口的实现类,在调用接口中的方法时,会执行InvocationHandler的invoke()方法,返回值也是方法的返回值,就是走的正常的动态代理流程
2、传入数组大小问0的Class数组

如果是这样传值的话,那么,代理的接口就是toString()方法,且不能将返回的对象强转为接口类型,因为返回值对象已经变成了,invoke方法返回的,也只有在使用返回值对象时,才会触发invoke方法
例如:

- InvocationHandler
代理对象,通过动态代理生成出的对象,调用对象方法,实际调用的就是InvocationHandler对象的invoke方法,可以自定义一个类,实现InvocationHandler接口,也可以在Proxy.newProxyInstance的时候通过lambda表达式实现invoke方法。



版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/53790.html