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
润饰的属性名,而后在提供 get
和 set
办法,如果有须要咱们能够在通过非属性操作相干的办法。本章就临时是对前两者的一个探讨。
首先咱们来定义一个根本的 Java Bean
public 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
成员变量表
变量名称
变量类型
变量阐明
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;}
编写这段代码的次要逻辑如下
- 通过
Class
获取BeanInfo
接口 - 通过
BeanInfo
获取beanClass
- 通过
beanClass
提取构造函数列表,从构造函数列表中抉择一个具体的构造函数(这里采纳无参结构的形式) - 获取属性形容对象进行属性设置
编写实现后咱们来写测试用例
@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 有什么关系呢?咱们能够思考上面几个问题
- 晓得了
BeanClass
如何能力创建对象呢? - 晓得属性名称和属性值如何给对象赋值呢?
这两个问题的答案很简略就是通过 Java 反射机制来进行解决,那么具体怎么做呢?这个问题的答案其实就是咱们后面所编写的那段创建对象的代码。回过头咱们来看这两个问题
- 第一个问题的答案:创建对象其本质是寻找构造函数并调用
- 第二个问题的答案:通过找到写办法将数据写入
- 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;}
其余的一些生命周期接口也是能够通过相似的解决形式进行补充,笔者就不在这里进行开展了。