反射与动态代理

记录反射与动态代理相关的知识点


反射api记录:

https://www.jianshu.com/p/e55770dd48d3

setAccessible(boolean flag) //true表示取消访问权限检查
含有Declared的,可以获取所有权限
非Declared的,只能获取public

Class对象

//第一种方式 通过Class类的静态方法——forName()来实现
class1 = Class.forName(“com.lvr.reflection.Person”);
//第二种方式 通过类的class属性
class1 = Person.class;
//第三种方式 通过对象getClass方法
Person person = new Person();
Class<?> class1 = person.getClass();

获取 Class 对应类的成员变量

Field[] getDeclaredFields(); 
// 获取 Class 对象对应类的所有属性,与成员变量的访问权限无关。
Field getDeclaredField(String name);
// 获取 Class 对象对应类的指定名称的属性,与成员变量的访问权限无关。
Field[] getFields(); 
// 获取 Class 对象对应类的所有 public 属性
Field getField(String name);
// 获取 Class 对象对应类的指定名称的 public 属性。

获取 Class 对应类的方法

Method[] getDeclaredMethods();
// 获取 Class 对象对应类的所有声明方法,于方法的访问权限无关。
Method getDeclaredMethod(String name, Class...parameterTypes); // 返回此 Class 对象对应类的、带指定形参列表的方法,与方法的访问权限无关。 Method[] getMethods(); // 获取 Class 对象对应类的所有 public 方法,包括父类的方法。 Method getMethod(String name, Class…parameterTypes);
// 返回此 Class 对象对应类的、带指定形参列表的 public 方法。

创建对象

1.使用 Class 对象的 newInstance() 方法(要求:Class 对象的对应类要有默认构造器)
2.先使用 Class 对象获取指定的 Constructor 对象,再调用 Constructor 对象的 newInstance() 方法(这种方式可以选择使用指定的构造器来创建实例。)

调用方法

method.invoke(Object obj, Object… args)
obj是method的调用者,args是method的参数

获取对象xxx

field.get(A)//field是A的普通变量
field.get(null)//field是A的静态变量

替换对象

field.set(obj,newValue)//field是obj对象的属性/变量


动态代理:

https://juejin.cn/post/7275185537815183360

https://juejin.cn/post/6844903978342301709

动态代理是一种通过创建代理对象来代替原始对象的技术,以便在方法调用前后执行额外的操作。代理对象通常实现与原始对象相同的接口,但可以添加自定义行为。动态代理是在运行时生成的,因此它不需要在编译时知道原始对象的类型。

通过反射机制动态生成代理者对象的一种设计模式。

1
Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h); 
1
2
//回调h的invoke方法
invoke(thisObject proxy, Method method, Object[] args);
1
2
//在上述方法中
return method.invoke(Object obj, Object... args);

可以在上述第三步的前后分别执行自定义的逻辑

详细代码可以查看 kotlinbox


如何区分静态代理和动态代理?

  • 静态代理:程序运行前,代理类已经存在。
  • 动态代理:程序运行前,代理类不存在,运行过程中,动态生成代理类。

动态代理的好处

1
2
3
4
5
6
7
8
9
10
11
// 接口 
interface MyInterface {
fun doSomething()
}

// 实现类
class MyImplementation : MyInterface {
override fun doSomething() {
println("Original method is called.")
}
}

静态代理类实现一样的接口,持有被代理类的实例A,再用A去调方法
如果接口发生变化,则静态代理类实现就要修改或者新增代理类

动态代理不需要修改,运行时生成代理类

只需要1个动态代理类就可以解决创建多个静态代理的问题,避免重复、多余代码


动态代理和反射

反射和动态代理都是在运行时处理类和对象的技术,但它们的应用场景不同。反射主要用于在运行时检查和操作类的信息,而动态代理主要用于在方法调用前后执行额外的逻辑。选择使用哪种技术取决于你的具体需求和设计目标。