一、类的加载
类的加载一共分为三步:
1、加载 就是将类加载进内存,并同时创建一个Class对象(就是描述一个 .class 文件的对象) 而且任何类被使用前都会先创建一个 Class对象 2、连接 验证 是否有正确的内部结构,并和其他类协调一致 准备 负责为类的静态成员分配内存,并设置默认初始化值 解析 将类的二进制数据中的符号引用替换为直接引用 3、初始化 见前面的初始化笔记。 初始化的时机: 创建类的实例 访问类的静态变量,或者为静态变量赋值 调用类的静态方法 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象 初始化某个类的子类 直接使用java.exe命令来运行某个主类二、类的加载器类加载器
负责将.class文件加载到内在中,并为之生成对应的Class对象。 类加载器的组成 1、Bootstrap ClassLoader 根类加载器 也被称为引导类加载器,负责Java核心类的加载 比如: System,String等。在JDK中JRE的lib目录下rt.jar文件中2、Extension ClassLoader 扩展类加载器 负责JRE的扩展目录中jar包的加载。 在JDK中JRE的lib目录下ext目录
3、Sysetm ClassLoader 系统类加载器
负责在JVM启动时加载来自java命令的class文件,
以及classpath环境变量所指定的jar包和类路径 (一般此加载器加载的就是我们所写的文件) 三、反射概念:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法; 对于任意一个对象,都能够调用它的任意一个方法和属性; 这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 就是通过一定的方法(如:通过 .class文件的文件名)来指向一个 .class文件,在获得一个用来 描述这个 .class文件的 Class 对象, 之后通过该Class对象来获取文件中的 构造方法、成员变量、成员方法, (既可以批量获取, 也可以单个获取,既可以获取public 类型的,也可获取private类型的, 甚至可以通过暴力访问的方法 来访问 private的成员。) 通过获取到的构造方法,可以得到一个Object型的该类对象,(Constructer) 通过获取到的成员 和 该类对象,可以操作.class文件中的成员了。(Field, Method) 获取Class对象: 1、Object的 getClass 方法。 2、数据类型的静态属性 class (引用类型、基本类型)。 3、Class类中的静态方法。 static Class<?> forName(String className) static Class<?> forName(String name, boolean initialize, ClassLoader loader) 获取构造方法: 获取构造方法 getConstructors(Class<?>... parameterTypes) getDeclaredConstructors() 创建对象 newInstance() con.newInstance(“zhangsan", 20); 获取成员变量: 获取所有成员 getFields, getDeclaredFields 获取单个成员 getField, getDeclaredField 修改成员的值 set(Object obj,Object value) 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。 获取成员方法: 获取所有方法 getMethods 获取所有的public成员变量(自己的和父类的) getDeclaredMethods 获取只属于自己的所有的变量。 获取单个方法 getMethod getDeclaredMethod 暴力访问 method.setAccessible(true);四、动态代理
动态代理: 在程序运行过程中产生的这个对象
而程序运行过程中产生对象其实就是我们刚才反射讲解的内容, 所以,动态代理其实就是通过反射来生成一个代理 就是说,我们需要对一个我们已有的对象的方法添加一些新的功能,而这些功能对每个对象、 每个方法都是相同的, 那么我们就可以使用动态代理来获得一个该对象的动态代理对象, 使用该对象再调用的方法,就是被动态代理过后的方法。 在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口, 通过使用这个类和接口就可以生成动态代理对象。JDK提供的代理只能针对接口做代理。 我们有更强大的代理cglib Proxy类中的方法创建动态代理类对象 public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) 最终会调用InvocationHandler的方法 InvocationHandler Object invoke(Object proxy,Method method,Object[] args)1 public class MyBeanFactory { 2 3 public static UserService createService(){ 4 //1 目标类 5 final UserService userService = new UserServiceImpl(); 6 //2切面类 7 final MyAspect myAspect = new MyAspect(); 8 /* 3 代理类:将目标类(切入点)和 切面类(通知) 结合 --> 切面 9 * Proxy.newProxyInstance10 * 参数1:loader ,类加载器,动态代理类 运行时创建,任何类都需要类加载器将其加载到内存。11 * 一般情况:当前类.class.getClassLoader();12 * 目标类实例.getClass().get...13 * 参数2:Class[] interfaces 代理类需要实现的所有接口14 * 方式1:目标类实例.getClass().getInterfaces() ;注意:只能获得自己接口,不能获得父元素接口15 * 方式2:new Class[]{UserService.class} 16 * 例如:jdbc 驱动 --> DriverManager 获得接口 Connection17 * 参数3:InvocationHandler 处理类,接口,必须进行实现类,一般采用匿名内部18 * 提供 invoke 方法,代理类的每一个方法执行时,都将调用一次invoke19 * 参数31:Object proxy :代理对象20 * 参数32:Method method : 代理对象当前执行的方法的描述对象(反射)21 * 执行方法名:method.getName()22 * 执行方法:method.invoke(对象,实际参数)23 * 参数33:Object[] args :方法实际参数24 * 25 */26 UserService proxService = (UserService)Proxy.newProxyInstance(27 MyBeanFactory.class.getClassLoader(), 28 userService.getClass().getInterfaces(), 29 new InvocationHandler() {30 31 @Override32 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {33 34 //前执行35 myAspect.before();36 37 //执行目标类的方法38 Object obj = method.invoke(userService, args);39 40 //后执行41 myAspect.after();42 43 return obj;44 }45 });46 47 return proxService;48 }49 50 }
1 public class MyBeanFactory { 2 3 public static UserServiceImpl createService(){ 4 //1 目标类 5 final UserServiceImpl userService = new UserServiceImpl(); 6 //2切面类 7 final MyAspect myAspect = new MyAspect(); 8 // 3.代理类 ,采用cglib,底层创建目标类的子类 9 //3.1 核心类10 Enhancer enhancer = new Enhancer();11 //3.2 确定父类12 enhancer.setSuperclass(userService.getClass());13 /* 3.3 设置回调函数 , MethodInterceptor接口 等效 jdk InvocationHandler接口14 * intercept() 等效 jdk invoke()15 * 参数1、参数2、参数3:以invoke一样16 * 参数4:methodProxy 方法的代理17 * 18 * 19 */20 enhancer.setCallback(new MethodInterceptor(){21 22 @Override23 public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {24 25 //前26 myAspect.before();27 28 //执行目标类的方法29 Object obj = method.invoke(userService, args);30 // * 执行代理类的父类 ,执行目标类 (目标类和代理类 父子关系)31 methodProxy.invokeSuper(proxy, args);32 33 //后34 myAspect.after();35 36 return obj;37 }38 });39 //3.4 创建代理40 UserServiceImpl proxService = (UserServiceImpl) enhancer.create();41 42 return proxService;43 }44 45 }
五、属性描述器
BeanInfo :一个描述对象的类
PropertyDiscriptor:属性描述器(获得某个对象的某个属性的描述器)
pd.setReadMethod():得到set属性(返回Method)
m.invoke(对象,值):为该对象该属性赋值
六、内省
BeanUtils.setProperty(对象,属性,值):给该对象的该属性复制(8种基本数据类型可以互相转换,get类似)
BeanUtils.populate(对象名,Map集合):通过一个Map集合中的数据为对象中的所有属性赋值
ConvertUtils.register(Convert,要装换成的数据类型);类型转换器
Convert:接口,下有各种转换对象:DateLocalConvert等。