Java Beans

在这一章章节中笔者将和各位一起探讨对于 Java Beans 相干的内容。本章次要围绕 java.beans 这个包门路下的代码进行一些阐明。

在 Spring 中咱们能够看到 BeanInfoFactory 该接口能够用来获取 Class 对应的 BeanInfo 对象,在 CachedIntrospectionResults 中也有相干的成员变量作为信息存储,其余中央还有笔者就不再这里都去搜寻了,各位能够自行查阅。

  • BeanInfoFactory

    public interface BeanInfoFactory {@Nullable   BeanInfo getBeanInfo(Class<?> beanClass) throws IntrospectionException;} 
  • CachedIntrospectionResults

    public final class CachedIntrospectionResults {    private final BeanInfo beanInfo;} 

对于 Spring 来说操作 Bean 自身的内容其实是操作各类属性及其提供的办法。从笔者的角度来看 Bean 这个对象我感觉能够分成这三种,第一种是对于 Bean 属性的,第二种是对于属性操作的办法,第三种是提供内部操作的办法。就比如说当初有一个 People 对象,存在多个属性,咱们在对这个 Bean 对象定义的时候失常状况下咱们会放入 private 润饰的属性名,而后在提供 getset 办法,如果有须要咱们能够在通过非属性操作相干的办法。本章就临时是对前两者的一个探讨。

首先咱们来定义一个根本的 Java Bean

public class Student {   private String name;   public String getName() {      return name;   }   public void setName(String name) {      this.name = name;   }} 

当初咱们用了一个名字叫做 Student 的 Java 对象,咱们来看这个对象的解释

  1. Student 对象中具备属性 name
  2. 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 成员变量表

变量名称

变量类型

变量阐明

beanClassRef

Reference<? extends Class<?>>

bean 的类

customizerClassRef

Reference<? extends Class<?>>

自定义的类

  • PropertyDescriptor 成员变量表

变量名称

变量类型

变量阐明

propertyTypeRef

Reference<? extends Class<?>>

属性类型

readMethodRef

MethodRef

读办法

writeMethodRef

MethodRef

写办法

propertyEditorClassRef

Reference<? extends Class<?>>

属性编辑类型

bound

boolean

constrained

boolean

baseName

String

writeMethodName

String

写办法名称

readMethodName

String

读办法名称

  • MethodDescriptor 成员变量表

变量名称

变量类型

变量阐明

methodRef

MethodRef

办法

paramNames

String[]

参数名称

params

List<WeakReference<Class<?>>>

参数信息

parameterDescriptors

ParameterDescriptor

参数形容

在理解了上述三个对象后咱们来编写一个测试用例,该测试用例次要用来获取 BeanInfo 接口数据

  • BeanInfo 测试用例
@Testvoid classTest() throws IntrospectionException {   Class clazz  = Student.class;   BeanInfo beanInfo = Introspector.getBeanInfo(clazz);   System.out.println();} 
  • BeanInfo 信息

咱们当初对 BeanInfo 有了肯定的理解,接下来咱们要通过 BeanInfo 来创立一个对象,并给该对象进行数据赋值,上面咱们来写代码

@NotNullprivate <T> T getObject(Class<T> clazz, Map<String, Object> prop) throws Exception {   // 获取 BeanInfo 接口   BeanInfo beanInfo = Introspector.getBeanInfo(clazz);   // 获取 Bean Class   Class<?> 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;} 

编写这段代码的次要逻辑如下

  1. 通过 Class 获取 BeanInfo 接口
  2. 通过 BeanInfo 获取 beanClass
  3. 通过 beanClass 提取构造函数列表,从构造函数列表中抉择一个具体的构造函数(这里采纳无参结构的形式)
  4. 获取属性形容对象进行属性设置

编写实现后咱们来写测试用例

@Testvoid beanInfoCreateBean() throws Exception {   Class<Student> clazz = Student.class;   // 设置属性表   Map<String, Object> 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 模式的时候会编写上面这样的内容。

<bean id="people" class="com.source.hot.ioc.book.pojo.PeopleBean">    <property name="name" value="zhangsan"/></bean> 

这里咱们抛开 Spring 中 Bean 生命周期相干的一些接口、占位符解析等内容,咱们就简略的来看这个 <bean> 标签,这个标签定义了一个 class 属性 和子标签 property ,咱们能够通过一些 XML 解析工具失去这两个对象,Spring 在这会将 class 属性通过 ClassLoader 转换成 Class 会将 property 转换成对象 PropertyValue ,而后通过反射将对象创立进去。那么这段阐明和咱们所编写的通过 BeanInfo 创立 Bean 有什么关系呢?咱们能够思考上面几个问题

  1. 晓得了 BeanClass 如何能力创建对象呢?
  2. 晓得属性名称和属性值如何给对象赋值呢?

这两个问题的答案很简略就是通过 Java 反射机制来进行解决,那么具体怎么做呢?这个问题的答案其实就是咱们后面所编写的那段创建对象的代码。回过头咱们来看这两个问题

  1. 第一个问题的答案:创建对象其本质是寻找构造函数并调用
  2. 第二个问题的答案:通过找到写办法将数据写入
  • Spring 中无参构造函数的调用

  • 有参结构的推论过程

在这里做出了两种构造函数的推论,当实现推论构造函数后就能够进行对象创立及属性赋值了。

属性赋值相干的代码就不在截图了各位能够自行查找。

当咱们有了 getObject 这样一个办法后,咱们再来看一些生命周期,Spring 当中的各类生命周期其实就是围绕者这段代码的前起初做各种补充操作,

比方 InitializingBean 这个接口的调用时在 Bean 创立实现后,那么咱们能够在具体的地位上补充这样一段

  • 批改后的 getObject
@NotNullprivate <T> T getObject(Class<T> clazz, Map<String, Object> prop) throws Exception {   // 获取 BeanInfo 接口   BeanInfo beanInfo = Introspector.getBeanInfo(clazz);   // 获取 Bean Class   Class<?> beanClass = beanInfo.getBeanDescriptor().getBeanClass();   // 获取所有的构造函数   Constructor<?>[] declaredConstructors = beanClass.getDeclaredConstructors();   // 确认构造函数: 间接取无参结构   Constructor constructor = confirmConstructor(declaredConstructors);   // 通过构造函数获取对象   https://www.douban.com/doulist/136178634/https://m.douban.com/doulist/136178634/https://book.douban.com/doulist/136178634/https://movie.douban.com/doulist/136178634/https://www.douban.com/doulist/136178636/https://m.douban.com/doulist/136178636/https://book.douban.com/doulist/136178636/https://movie.douban.com/doulist/136178636/https://www.douban.com/doulist/136178639/https://m.douban.com/doulist/136178639/https://book.douban.com/doulist/136178639/https://movie.douban.com/doulist/136178639/https://www.douban.com/doulist/136178642/https://m.douban.com/doulist/136178642/https://book.douban.com/doulist/136178642/https://movie.douban.com/doulist/136178642/https://www.douban.com/doulist/136178646/https://m.douban.com/doulist/136178646/https://book.douban.com/doulist/136178646/https://movie.douban.com/doulist/136178646/https://www.douban.com/doulist/136178647/https://m.douban.com/doulist/136178647/https://book.douban.com/doulist/136178647/https://movie.douban.com/doulist/136178647/https://www.douban.com/doulist/136178648/https://m.douban.com/doulist/136178648/https://book.douban.com/doulist/136178648/https://movie.douban.com/doulist/136178648/https://www.douban.com/doulist/136178655/https://m.douban.com/doulist/136178655/https://book.douban.com/doulist/136178655/https://movie.douban.com/doulist/136178655/https://www.douban.com/doulist/136178658/https://m.douban.com/doulist/136178658/https://book.douban.com/doulist/136178658/https://movie.douban.com/doulist/136178658/https://www.douban.com/doulist/136178660/https://m.douban.com/doulist/136178660/https://book.douban.com/doulist/136178660/https://movie.douban.com/doulist/136178660/https://www.douban.com/doulist/136178664/https://m.douban.com/doulist/136178664/https://book.douban.com/doulist/136178664/https://movie.douban.com/doulist/136178664/https://www.douban.com/doulist/136178668/https://m.douban.com/doulist/136178668/https://book.douban.com/doulist/136178668/https://movie.douban.com/doulist/136178668/https://www.douban.com/doulist/136178672/https://m.douban.com/doulist/136178672/https://book.douban.com/doulist/136178672/https://movie.douban.com/doulist/136178672/https://www.douban.com/doulist/136178675/https://m.douban.com/doulist/136178675/https://book.douban.com/doulist/136178675/https://movie.douban.com/doulist/136178675/https://www.douban.com/doulist/136178677/https://m.douban.com/doulist/136178677/https://book.douban.com/doulist/136178677/https://movie.douban.com/doulist/136178677/https://www.douban.com/doulist/136178680/https://m.douban.com/doulist/136178680/https://book.douban.com/doulist/136178680/https://movie.douban.com/doulist/136178680/https://www.douban.com/doulist/136178683/https://m.douban.com/doulist/136178683/https://book.douban.com/doulist/136178683/https://movie.douban.com/doulist/136178683/https://www.douban.com/doulist/136178685/https://m.douban.com/doulist/136178685/https://book.douban.com/doulist/136178685/https://movie.douban.com/doulist/136178685/https://www.douban.com/doulist/136178687/https://m.douban.com/doulist/136178687/https://book.douban.com/doulist/136178687/https://movie.douban.com/doulist/136178687/https://www.douban.com/doulist/136178691/https://m.douban.com/doulist/136178691/https://book.douban.com/doulist/136178691/https://movie.douban.com/doulist/136178691/https://www.douban.com/doulist/136178699/https://m.douban.com/doulist/136178699/https://book.douban.com/doulist/136178699/https://movie.douban.com/doulist/136178699/https://www.douban.com/doulist/136178700/https://m.douban.com/doulist/136178700/https://book.douban.com/doulist/136178700/https://movie.douban.com/doulist/136178700/https://www.douban.com/doulist/136178702/https://m.douban.com/doulist/136178702/https://book.douban.com/doulist/136178702/https://movie.douban.com/doulist/136178702/https://www.douban.com/doulist/136178705/https://m.douban.com/doulist/136178705/https://book.douban.com/doulist/136178705/https://movie.douban.com/doulist/136178705/https://www.douban.com/doulist/136178706/https://m.douban.com/doulist/136178706/https://book.douban.com/doulist/136178706/https://movie.douban.com/doulist/136178706/https://www.douban.com/doulist/136178707/https://m.douban.com/doulist/136178707/https://book.douban.com/doulist/136178707/https://movie.douban.com/doulist/136178707/https://www.douban.com/doulist/136178710/https://m.douban.com/doulist/136178710/https://book.douban.com/doulist/136178710/https://movie.douban.com/doulist/136178710/https://www.douban.com/doulist/136178712/https://m.douban.com/doulist/136178712/https://book.douban.com/doulist/136178712/https://movie.douban.com/doulist/136178712/https://www.douban.com/doulist/136178715/https://m.douban.com/doulist/136178715/https://book.douban.com/doulist/136178715/https://movie.douban.com/doulist/136178715/https://www.douban.com/doulist/136178717/https://m.douban.com/doulist/136178717/https://book.douban.com/doulist/136178717/https://movie.douban.com/doulist/136178717/https://www.douban.com/doulist/136178719/https://m.douban.com/doulist/136178719/https://book.douban.com/doulist/136178719/https://movie.douban.com/doulist/136178719/https://www.douban.com/doulist/136178723/https://m.douban.com/doulist/136178723/https://book.douban.com/doulist/136178723/https://movie.douban.com/doulist/136178723/https://www.douban.com/doulist/136178731/https://m.douban.com/doulist/136178731/https://book.douban.com/doulist/136178731/https://movie.douban.com/doulist/136178731/https://www.douban.com/doulist/136178733/https://m.douban.com/doulist/136178733/https://book.douban.com/doulist/136178733/https://movie.douban.com/doulist/136178733/https://www.douban.com/doulist/136178739/https://m.douban.com/doulist/136178739/https://book.douban.com/doulist/136178739/https://movie.douban.com/doulist/136178739/https://www.douban.com/doulist/136178744/https://m.douban.com/doulist/136178744/https://book.douban.com/doulist/136178744/https://movie.douban.com/doulist/136178744/https://www.douban.com/doulist/136178746/https://m.douban.com/doulist/136178746/https://book.douban.com/doulist/136178746/https://movie.douban.com/doulist/136178746/https://www.douban.com/doulist/136178748/https://m.douban.com/doulist/136178748/https://book.douban.com/doulist/136178748/https://movie.douban.com/doulist/136178748/https://www.douban.com/doulist/136178751/https://m.douban.com/doulist/136178751/https://book.douban.com/doulist/136178751/https://movie.douban.com/doulist/136178751/https://www.douban.com/doulist/136178756/https://m.douban.com/doulist/136178756/https://book.douban.com/doulist/136178756/https://movie.douban.com/doulist/136178756/https://www.douban.com/doulist/136178758/https://m.douban.com/doulist/136178758/https://book.douban.com/doulist/136178758/https://movie.douban.com/doulist/136178758/https://www.douban.com/doulist/136178759/https://m.douban.com/doulist/136178759/https://book.douban.com/doulist/136178759/https://movie.douban.com/doulist/136178759/https://www.douban.com/doulist/136178761/https://m.douban.com/doulist/136178761/https://book.douban.com/doulist/136178761/https://movie.douban.com/doulist/136178761/https://www.douban.com/doulist/136178763/https://m.douban.com/doulist/136178763/https://book.douban.com/doulist/136178763/https://movie.douban.com/doulist/136178763/https://www.douban.com/doulist/136178766/https://m.douban.com/doulist/136178766/https://book.douban.com/doulist/136178766/https://movie.douban.com/doulist/136178766/https://www.douban.com/doulist/136178768/https://m.douban.com/doulist/136178768/https://book.douban.com/doulist/136178768/https://movie.douban.com/doulist/136178768/https://www.douban.com/doulist/136178771/https://m.douban.com/doulist/136178771/https://book.douban.com/doulist/136178771/https://movie.douban.com/doulist/136178771/https://www.douban.com/doulist/136178774/https://m.douban.com/doulist/136178774/https://book.douban.com/doulist/136178774/https://movie.douban.com/doulist/136178774/https://www.douban.com/doulist/136178776/https://m.douban.com/doulist/136178776/https://book.douban.com/doulist/136178776/https://movie.douban.com/doulist/136178776/   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;} 

其余的一些生命周期接口也是能够通过相似的解决形式进行补充,笔者就不在这里进行开展了。