类的加载过程:

  1. 程序经过javac.exe命令以后,会生成一个或多个字节码文件,接着我们使用java.exe命令对某个字节码文件进行解释运行。相当于将某个字节码文件加载到内存中,此过程就称为类的加载。(加载到内存中的类,我们就称为运行时类
  2. 加载到内存中的运行时类,会缓存一定的时间。在此时间之内,我们可以通过不同的方式来获取此运行时类。

image.png

反射机制

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。


获取运行时类的方式


① 通过运行时类的对象.getClass( )方法
想要使用这种方式,必须明确具体的类,并创建对象
②调用运行时类的.class属性
任何数据类型都具备一个静态的属性.class来获取其对应的class对象,但是需要指定具体的类
③通过给定的类的字符串名称获取该类字节码文件对象
可以使用Class类中的forName方法(只需给定类的全类名,即可添加使用)

  1. /*
  2. 创建一个指定类的对象。
  3. classPath:指定类的全类名
  4. */
  5. public Object getInstance(String classPath) throws Exception {
  6. Class clazz = Class.forName(classPath);
  7. return clazz.newInstance();
  8. }

④使用类的加载器:ClassLoader

  1. /*
  2. classPath:指定类的全类名
  3. */
  4. public class RefectTest(){
  5. @Test
  6. public void getInstance() throws Exception {
  7. ClassLoader loader = RefectTest.class.getClassLoader();
  8. loader.loadClass(classPath);
  9. }
  10. }

获取类的字段

反射 - 图2

  • 可以通过filed.set()设置被私有化的值

动态代理的实现

动态代理是指客户通过代理类来调用其它对象的方法,并且是在程序运行时根据需要动态创建目标类的代理对象。

两个步骤:
步骤一:加载到内存中的被代理类,动态的创建一个代理类及其对象。

  1. class ProxyFactory{
  2. //调用此方法,返回一个代理类的对象。完成步骤一
  3. public static Object getProxyInstance(Object obj){//obj:被代理类的对象
  4. return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
  5. obj.getClass().getInterfaces(),handler);
  6. }
  7. }

Proxy.newProxyInstance( )需要传入三个参数:

  • 参数1:传入被代理类的类加载器
  • 参数2:传入被代理类需要实现的接口
  • 参数3:传入InvocationHandler接口对象(handler)

步骤二:通过InvocationHandler接口的实现类及其方法invoke(),其会自动的去调用被代理类中的同名方法

Spring框架中,面向切面思想大量采用了动态代理。