## java反射和动态代理以及ASM工具类的优点

记一次学习动态代理和工具类MethodAccess的好用之处

前言:
java中的反射类是java一个功能很强大的类,几乎所有的框架中都要使用到反射进行代理,动态代理是在java运行过程中动态调用方法的时候必须使用到的一种方式。
1.先看下jdk提供的动态代理的使用
使用jdk提供的接口和工具进行动态代理时,首先要实现一个InvocationHandler处理类。这个类将会被代理类作为参数传入到自己的invoke方法中。
## java反射和动态代理以及ASM工具类的优点_第1张图片
处理类实现handler接口
首先声明一个对象对应被代理的目标对象,用于后边的代理参数带入。
关键在于Proxy.newProxyInstance方法 第一个参数传入的是被代理类的对象类类型,第二个参数是挂载的接口,第三个是处理类自己。

这个接口的方法invoke实现
## java反射和动态代理以及ASM工具类的优点_第2张图片
虚拟机会在运行时使用你提供的类加载器,将所有指定的接口类加载进方法区,然后反射读取这些接口中的方法并结合处理器类生成一个代理类型。## java反射和动态代理以及ASM工具类的优点_第3张图片
代理类名字根据个数后边数字增加 这边为了对成员变量赋值使用了继承Proxy类,因为java是单继承的也就导致了jdk的动态代理只能代理接口,换成类是无法代理的。## java反射和动态代理以及ASM工具类的优点_第4张图片
除了对传入的方法进行处理,代理类还会从真实对象中代理三个Object类方法。equals,toString,Hashcode方法。
使用这种方式进行代理,调用代理类时必须知道实现类的方法属于哪个实现类## java反射和动态代理以及ASM工具类的优点_第5张图片
这点的设计并不优雅 但是动态代理的功能还是起到的,传入需要代理的类对象,用接口接受并调用方法。

下面记录个比较好用的工具类 可以进行动态代理
使用是在微服务项目中多个服务之间互相调用时可以使用restTemplate也可以使用feign 进行接口的声明,feign组件自己拼接并调用,接受返回,处理返回值等。但是这种方法的调用声明@feignClients 这个声明只能在类上声明 ,这个类想调用的服务只能一个类有一个(目前的理解,感觉没理解到位)。第二中方法是通过rest远程调用的方式,## java反射和动态代理以及ASM工具类的优点_第6张图片
通过rest调用的时候服务名和方法名作为参数传递 接受解析的时候底层使用了这个作为代理 将参数传入调用到服务的具体方法并将参数传递进去。(转了一大圈终于转回来了)。
然后就发现了这个动态代理的好用之处
首先使用上比较简单 直接传入被代理类的类对象 代理的方法和 参数 直接就能够代理到目标方法并返回值。
实现原理:
MethodAccess这个类是 reflectasm这个包中的类,asm是可以直接动态修改字节码文件,从而达到动态代理的功能ReflectASM是一个很小的java类库,他仅仅有5个类,但是却提供了非常高性能的属性操作,方法调用,构造函数传递依赖对象方法调用,他在底层使用了asm
动态构建出字节码,这相比于反射,直接方法的调用性能高出很多。
最重要的是这个类比反射类的性能要高 很多 我自己大概测了下时间 用这个代理的速度非常快,比jdk的动态代理反射花费的时间短很多,比较明显## java反射和动态代理以及ASM工具类的优点_第7张图片
第一个时间到第二个时间的间隔(原谅我没转化具体时间 但通过间隔大概能看出差距)
312-360是我使用asm进行代理的时间
360-775是我使用jdk的动态代理花费的时间
对于动态代理,还有一个肯定要提的就是cglib库提供的动态代理,能够对类进行代理 解决了jdk的缺陷,有时间再将cglib的代理使用和原理记录下来。

你可能感兴趣的:(java,设计模式,动态代理,asm,MethodAccess,反射,java)