内省概述
内省 (Introspector) 是 Java 语言对 JavaBean 类的属性, 事件和方法的默认处理方式
例如: 类 User 中有属性 name, 那么必定有 getName,setName 方法, 内省就是通过这两个方法来获取或者设置 name 属性的值.
JavaBean
就是一个满足了特定格式的 Java 类
需要提供无参数的构造方法.
属性私有.
对私有的属性提供 public 的 get/set 方法.
内省类库
java.beans.Introspector:
该类提供了 "了解目标 JavaBean 所支持的属性, 事件和方法" 的标准方式.
java.beans.BeanInfo:
该接口提供有关获取 JavaBean 的显式信息 (公共的属性, 方法, 事件等) 的方法.
java.beans.PropertyDescriptor:
该类描述 JavaBean 的属性信息. 注意, 该属性信息是通过 JavaBean 的 get/set 方法推导出的属性.
示例代码
? 1. 存在类 User
- public class Student {
- private String name;
- private int age;
- public Student() {
- }
- public Student(String name, int age) {
- this.name = name;
- this.age = age;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- ? [email protected]
- public String toString() {
- return "Student [name=" + name + ", age=" + age + "]";
- }
- }
2. 通过内省获取 User 类的所有属性:
- public class StudentTest {
- public static void main(String[] args) throws IntrospectionException {
- // 通过 Introspector.getBeanInfo 方法获取指定 JavaBean 类的 BeanInfo 信息
- BeanInfo beanInfo = Introspector.getBeanInfo(Student.class);
- // 通过 BeanInfo 的 getPropertyDescriptors 方法获取被操作的 JavaBean 类的所有属性
- // 注意, 该属性是通过 get/set 方法推断出来的属性
- PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
- // 遍历所有的属性
- for (PropertyDescriptor pd : pds) {
- // 获取属性的名字
- String propName = pd.getName();
- System.out.println(propName);
- // 获取属性的类型
- Class propType = pd.getPropertyType();
- System.out.println(propType);
- // 获取属性对应的 get 方法
- Method getMethod = pd.getWriteMethod();
- System.out.println(getMethod);
- // 获取属性对应的 set 方法
- Method setMethod = pd.getReadMethod();
- System.out.println(setMethod);
- }
- }
- }
3. 创建一个 User 对象, 通过内省, 设置该对象的 name 属性的值为 "张三丰"
- // 创建一个没有任何参数的 Student 对象 s
- Student s = new Student();
- // 通过 PropertyDescriptor 类的构造方法, 直接获取 Student 类的 name 属性
- PropertyDescriptor pd = new PropertyDescriptor("name",Student.class);
- // 获取 name 属性对应的 set 方法
- Method setMethod = pd.getWriteMethod();
- // 调用 set 方法给上边创建的 s 对象的 name 属性赋值
- setMethod.invoke(s, "张三丰");
- // 输出 s
- System.out.println(s);
4. 输出结果为:
Student [name = 张三丰, age=0]
应用场景
在很多 Javaweb 框架设计的时候, 会使用到内省机制.
如:
? Web 开发框架 Struts 中的 FormBean 就是通过内省机制来将表单中的数据映射到类的属性上.
? BeanUtils 框架的底层也是通过内省来操作 JavaBean 对象的.
BeanUtils
BeanUtils 是一个由 Apache 软件基金组织编写的, 专门用来操作 JavaBean 对象的一个工具.
主要解决的问题是: 可以把对象的属性数据封装到对象中.
它的底层, 就是通过内省来实现的.
- // 向 Map 集合中封装数据 -- 模拟在 javaWeb 中, 使用 request.getParameterMap() 获取的参数数据;
- Map<String, Object> map = new HashMap<String, Object>() ;
- map.put("name", "张三丰") ;
- map.put("age", 200) ;
- ?
- // 创建一个 Student 对象
- Student s = new Student();
- // 通过 BeanUtils 的 populate 方法, 可以把 Map 集合中的数据封装到 Student 中
- // 该方法的底层就是通过内省来实现的
- BeanUtils.populate(s, map);
扩展
内省机制是通过反射来实现的
来源: http://www.bubuko.com/infodetail-3202680.html