知识总结之 插件化基础 java反射与代理
Java平台的反射机制是代码动态加载和调用的基本途径,在安卓系统源码中也用到了大量的反射动态加载类。反射也是安卓平台插件化实现的必要掌握的基础知识。代理是客户端灵活操作对象,间接的低耦合度操作对象的有效途径,也是插件化必要掌握知识。
安卓插件化基础 java反射与代理
一、反射
java中反射机理比较常用,这里主要以代码实例展示其用法。
什么是反射?
指程序运行时 加载、获取一个未知类(已知类名)及类属性和方法的java技术机理。加载完成后会在虚拟机中产生一个class对象,一个类只有一个class对象,这个class对象包含了类的相关结构信息。
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Class对象如何获取?
- 运用Class.forName(String className)动态加载类;
- .class 属性(轻量级);
- getClass()方法;
对象的创建
- 使用Class对象的newInstance()方法来创建该Class对象对应类的实例,这种方式要求该Class对象的对应类有默认构造器。
- 先使用Class对象获取指定的Constructor对象, 再调用Constructor对象的newInstance()。通过这种方式可以选择指定的构造器来创建实例。
|
|
相关Api相关实例
先定义一个bean类作为反射对象
|
|
1.对象实例化
|
|
2. 获取实现接口列表
|
|
3.获取父类
|
|
4.获取类属性
|
|
想要获取父类中属性怎么办?getSuperclass()先获取父类实例,然后调用getDeclaredFields()获取。可以依次遍历super类,获得全部继承关系中的属性。
5.获取类方法
|
|
6.方法及属性的操作
|
|
二、代理
什么是java代理模式?
代理用到类反射的知识,这里进一步单独讲解加深理解。
对某个对象提供一个代理对象,使得我们可以通过代理对象间接的操作原对象。
静态代理:代码层通过设计类获得一个中间层代理,是在编译时已经实现好的,可以说是一个class文件。
动态代理:代理类是在运行时由java机理产生。起到动态调用和操作代码的目的。
由于静态代理比较简单,易于理解,本文主要讲解动态代理。
基本概念
InvocationHandler接口
代理类调用任何方法都会经过这个调用处理器类的invoke方法。
Proxy
主要用于产生代理类,通过 Proxy 类生成的代理类都继承了 Proxy 类。newProxyInstance方法封装了获取代理对象。
newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h);方法传如的参数可以看出,代理一个对象,必须要要满足这个对象实现一个接口。
动态代理实现方法
个人学习习惯,学习新知识,先了解大概,然后就是代码,最后看原理,有精力的话就写点东西分享出来。这里就先看下代码如何实现一个动态代理。
只要一个类满足代理条件,即可实现代理。
|
|
|
|
代理类的每次方法调用,都会触发proxyHandler的invoke方法,这样我们就可以在此时做一些自己的事情。
android系统中有些类也是满足代理条件的,这样我们同样可以做一个代理类,来实现hook系统部分方法的目的。
实现原理
首先来看下newProxyInstance源码
|
|
可以看出getProxyClass0()方法为生成代理类关键方法
|
|
看到源码注释,如果代理类在传入的classloader中已经加载则直接返回,否则会在ProxyClassFactory中生成。
proxyClassCache.get方法中有以下代码
|
|
结合代码和注释可以大概看出subKeyFactory.apply(key, parameter)返回的就是代理类
那我们具体看看apply是怎么生产我们的代理类的:
|
|
最终ProxyGenerator.generateProxyClass方法中产生类代理类并写入磁盘。这种操作代码的代码java总称为元编程,java SOURCE级别的注解中也会大量用到。
代理类最终生产的样子如下:
|
|
从代理来结构,可以看出为什么每次方法的调用都会掉到invocationHandler的invoke方法。
——————
欢迎转载,请标明出处:常兴E站 www.canking.win