类的加载过程:
- 程序经过javac.exe命令以后,会生成一个或多个字节码文件,接着我们使用java.exe命令对某个字节码文件进行解释运行。相当于将某个字节码文件加载到内存中,此过程就称为类的加载。(加载到内存中的类,我们就称为运行时类)
- 加载到内存中的运行时类,会缓存一定的时间。在此时间之内,我们可以通过不同的方式来获取此运行时类。
反射机制
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
获取运行时类的方式
① 通过运行时类的对象.getClass( )方法
想要使用这种方式,必须明确具体的类,并创建对象
②调用运行时类的.class属性
任何数据类型都具备一个静态的属性.class来获取其对应的class对象,但是需要指定具体的类
③通过给定的类的字符串名称获取该类字节码文件对象
可以使用Class类中的forName方法(只需给定类的全类名,即可添加使用)
/*
创建一个指定类的对象。
classPath:指定类的全类名
*/
public Object getInstance(String classPath) throws Exception {
Class clazz = Class.forName(classPath);
return clazz.newInstance();
}
④使用类的加载器:ClassLoader
/*
classPath:指定类的全类名
*/
public class RefectTest(){
@Test
public void getInstance() throws Exception {
ClassLoader loader = RefectTest.class.getClassLoader();
loader.loadClass(classPath);
}
}
获取类的字段
- 可以通过filed.set()设置被私有化的值
动态代理的实现
动态代理是指客户通过代理类来调用其它对象的方法,并且是在程序运行时根据需要动态创建目标类的代理对象。
两个步骤:
步骤一:加载到内存中的被代理类,动态的创建一个代理类及其对象。
class ProxyFactory{
//调用此方法,返回一个代理类的对象。完成步骤一
public static Object getProxyInstance(Object obj){//obj:被代理类的对象
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),handler);
}
}
Proxy.newProxyInstance( )需要传入三个参数:
- 参数1:传入被代理类的类加载器
- 参数2:传入被代理类需要实现的接口
- 参数3:传入InvocationHandler接口对象(handler)
步骤二:通过InvocationHandler接口的实现类及其方法invoke(),其会自动的去调用被代理类中的同名方法
Spring框架中,面向切面思想大量采用了动态代理。