网站开发推广,网站制作加盟,中国河北建设银行官网招聘网站,建筑设计总说明模板Java Beans在这一章章节中笔者将和各位一起探讨关于 Java Beans 相关的内容。本章主要围绕 java.beans 这个包路径下的代码进行一些说明。在 Spring 中我们可以看到 BeanInfoFactory 该接口可以用来获取 Class 对应的 BeanInfo 对象#xff0c;在 CachedIntrospectionResults …Java Beans在这一章章节中笔者将和各位一起探讨关于 Java Beans 相关的内容。本章主要围绕 java.beans 这个包路径下的代码进行一些说明。在 Spring 中我们可以看到 BeanInfoFactory 该接口可以用来获取 Class 对应的 BeanInfo 对象在 CachedIntrospectionResults 中也有相关的成员变量作为信息存储其他地方还有笔者就不再这里都去搜索了各位可以自行查阅。BeanInfoFactory public interface BeanInfoFactory {NullableBeanInfo getBeanInfo(Class beanClass) throws IntrospectionException;}CachedIntrospectionResults public final class CachedIntrospectionResults {private final BeanInfo beanInfo;}对于 Spring 来说操作 Bean 本身的内容其实是操作各类属性及其提供的方法。从笔者的角度来看 Bean 这个对象我觉得可以分成这三种第一种是关于 Bean 属性的第二种是关于属性操作的方法第三种是提供外部操作的方法。就比如说现在有一个 People 对象存在多个属性我们在对这个 Bean 对象定义的时候正常情况下我们会放入 private 修饰的属性名然后在提供 get 和 set 方法如果有需要我们可以在通过非属性操作相关的方法。本章就暂时是对前两者的一个讨论。首先我们来定义一个基本的 Java Beanpublic class Student {private String name;public String getName() {return name;}public void setName(String name) {this.name name;}}现在我们用了一个名字叫做 Student 的 Java 对象我们来看这个对象的解释在 Student 对象中具有属性 name在 Student 对象中存在字段 name我们通常情况下会有这两种对象的定义解释那么这个定义解释在 Java 中是如何对其进行定义的呢。在 Java 中有一个接口叫做 java.beans.BeanInfo 这个接口是用来描述 Java Bean 的接口下面我们来看这个接口中存在的方法BeanInfo 方法信息public interface BeanInfo {BeanDescriptor getBeanDescriptor();EventSetDescriptor[] getEventSetDescriptors();int getDefaultEventIndex();PropertyDescriptor[] getPropertyDescriptors();int getDefaultPropertyIndex();MethodDescriptor[] getMethodDescriptors();BeanInfo[] getAdditionalBeanInfo();}getBeanDescriptor 返回 Bean 的描述信息getEventSetDescriptors返回 Bean 相关的事件信息getDefaultEventIndex返回 Bean 默认事件索引getPropertyDescriptors返回 Bean 属性描述getDefaultPropertyIndex返回 Bean 默认的属性索引getMethodDescriptors返回 Bean 方法描述getAdditionalBeanInfo 返回其他的 Bean Info 信息下面我们先来对接口中的返回值做一些介绍BeanDescriptor 成员变量表变量名称变量类型变量说明beanClassRefReference extends Classbean 的类customizerClassRefReference extends Class自定义的类PropertyDescriptor 成员变量表变量名称变量类型变量说明propertyTypeRefReference extends Class属性类型readMethodRefMethodRef读方法writeMethodRefMethodRef写方法propertyEditorClassRefReference extends Class属性编辑类型boundbooleanconstrainedbooleanbaseNameStringwriteMethodNameString写方法名称readMethodNameString读方法名称MethodDescriptor 成员变量表变量名称变量类型变量说明methodRefMethodRef方法paramNamesString[]参数名称paramsList参数信息parameterDescriptorsParameterDescriptor参数描述在了解了上述三个对象后我们来编写一个测试用例该测试用例主要用来获取 BeanInfo 接口数据BeanInfo 测试用例Testvoid classTest() throws IntrospectionException {Class clazz Student.class;BeanInfo beanInfo Introspector.getBeanInfo(clazz);System.out.println();}BeanInfo 信息我们现在对 BeanInfo 有了一定的了解接下来我们要通过 BeanInfo 来创建一个对象并给该对象进行数据赋值下面我们来写代码NotNullprivate T getObject(Class clazz, Map prop) throws Exception {// 获取 BeanInfo 接口BeanInfo beanInfo Introspector.getBeanInfo(clazz);// 获取 Bean ClassClass beanClass beanInfo.getBeanDescriptor().getBeanClass();// 获取所有的构造函数Constructor[] declaredConstructors beanClass.getDeclaredConstructors();// 确认构造函数: 直接取无参构造Constructor constructor confirmConstructor(declaredConstructors);// 通过构造函数获取对象Object bean constructor.newInstance();// 为对象设置属性// 提取属性描述PropertyDescriptor[] propertyDescriptors beanInfo.getPropertyDescriptors();for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {// 属性名称String name propertyDescriptor.getName();if (prop.containsKey(name)) {// 写函数Method writeMethod propertyDescriptor.getWriteMethod();// 从属性表中获取属性名称对应的属性值Object proValue prop.get(name);writeMethod.invoke(bean, proValue);}}return (T) bean;}编写这段代码的主要逻辑如下通过 Class 获取 BeanInfo 接口通过 BeanInfo 获取 beanClass通过 beanClass 提取构造函数列表从构造函数列表中选择一个具体的构造函数(这里采用无参构造的方式)获取属性描述对象进行属性设置编写完成后我们来写测试用例Testvoid beanInfoCreateBean() throws Exception {Class clazz Student.class;// 设置属性表Map prop new HashMap(8);prop.put(name, student_name);Student bean getObject(clazz, prop);assert bean.getName().equals(student_name);}这样我们就完成了数据赋值在上述过程中我们对于 beanClass 的获取可以直接使用参数传递的 clazz 直接使用可以不需要通过 BeanInfo 接口进行二次调度。下面我们来谈一谈 Spring 和 BeanInfo 的一些关联。相信各位在使用 Spring XML 模式的时候会编写下面这样的内容。这里我们抛开 Spring 中 Bean 生命周期相关的一些接口、占位符解析等内容我们就简单的来看这个 标签这个标签定义了一个 class 属性 和子标签 property 我们可以通过一些 XML 解析工具得到这两个对象Spring 在这会将 class 属性通过 ClassLoader 转换成 Class 会将 property 转换成对象 PropertyValue 然后通过反射将对象创建出来。那么这段说明和我们所编写的通过 BeanInfo 创建 Bean 有什么关系呢我们可以思考下面几个问题知道了 BeanClass 如何才能创建对象呢知道属性名称和属性值如何给对象赋值呢这两个问题的答案很简单就是通过 Java 反射机制来进行处理那么具体怎么做呢这个问题的答案其实就是我们前面所编写的那段创建对象的代码。回过头我们来看这两个问题第一个问题的答案创建对象其本质是寻找构造函数并调用第二个问题的答案通过找到写方法将数据写入Spring 中无参构造函数的调用有参构造的推论过程在这里做出了两种构造函数的推论当完成推论构造函数后就可以进行对象创建及属性赋值了。属性赋值相关的代码就不在截图了各位可以自行查找。当我们有了 getObject 这样一个方法后我们再来看一些生命周期Spring 当中的各类生命周期其实就是围绕者这段代码的前后来做各种补充操作比如 InitializingBean 这个接口的调用时在 Bean 创建完成后那么我们可以在具体的位置上补充这样一段修改后的 getObjectNotNullprivate T getObject(Class clazz, Map prop) throws Exception {// 获取 BeanInfo 接口BeanInfo beanInfo Introspector.getBeanInfo(clazz);// 获取 Bean ClassClass beanClass beanInfo.getBeanDescriptor().getBeanClass();// 获取所有的构造函数Constructor[] declaredConstructors beanClass.getDeclaredConstructors();// 确认构造函数: 直接取无参构造Constructor constructor confirmConstructor(declaredConstructors);// 通过构造函数获取对象Object bean constructor.newInstance();// 为对象设置属性// 提取属性描述PropertyDescriptor[] propertyDescriptors beanInfo.getPropertyDescriptors();for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {// 属性名称String name propertyDescriptor.getName();if (prop.containsKey(name)) {// 写函数Method writeMethod propertyDescriptor.getWriteMethod();// 从属性表中获取属性名称对应的属性值Object proValue prop.get(name);writeMethod.invoke(bean, proValue);}}if (bean instanceof InitializingBean) {((InitializingBean) bean).afterPropertiesSet();}return (T) bean;}其他的一些生命周期接口也是可以通过类似的处理方式进行补充笔者就不在这里进行展开了。