Listen to the sediment spread… Pay attention to wechat public number [Java], help you give up the path of programming!


I. Introduction to Introspector

Official introduction:

The Introspector class provides a standard way for tools to learn about the properties, events, and methods supported by a target Java Bean.

For each of those three kinds of information, the Introspector will separately analyze the bean’s class and superclasses looking for either explicit or implicit information and use that information to build a BeanInfo object that comprehensively describes the target bean.

Java.beans. Introspector Provides standard handling methods for accessing properties, events, and methods of Java beans.

For each of the three types of information about a Java Bean, the Introspector looks for and analyzes both explicit and implicit information about the Java Bean and its parent class, and then builds a BeanInfo object that fully describes the Java Bean.

In Java, Javabeans are a special class that is primarily used to pass data information. For example, DTO, VO, etc., we pass information between businesses or modules and can encapsulate information in Javabeans. Now that it is encapsulated in a JavaBean, there are operations to set (setters) and read (getters) properties in a JavaBean. Introspector does this for us, but be aware that getters and setters and other methods in Javabeans follow some specification.

The bottom layer makes full use of the principle of reflection to manipulate class attributes.

package com.nobody;

/ * * *@DescriptionJavaBean classes *@Author Mr.nobody
 * @Date 2021/1/24
 * @Version1.0 * /
public class Person {
    private String id;
    private String name;
    private int age;
    
	public Person(String id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public String getId(a) {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName(a) {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge(a) {
        return age;
    }

    public void setAge(int age) {
        this.age = age; }}Copy the code
// Get the BeanInfo of the Person class
BeanInfo beanInfo = Introspector.getBeanInfo(Person.class);
Copy the code


Introduction to BeanInfo

Official introduction:

Use the BeanInfo interface to create a BeanInfo class and provide explicit information about the methods, properties, events, and other features of your beans.

In short, the Java.beans.beaninfo interface creates a BeanInfo object that provides explicit information about javabeans’ methods, properties, events, and other characteristics. The main methods are as follows:

  • GetPropertyDescriptors () : Get the property descriptor.
  • GetBeanDescriptor () : Gets the object descriptor.
  • GetMethodDescriptors: Gets the method descriptor.

3. Introduction to PropertyDescriptor

Official introduction:

A PropertyDescriptor describes one property that a Java Bean exports via a pair of accessor methods.

Java. Beans. PropertyDescriptor, namely the property description. Represents a property that a Java Bean exports through a storage method. You can simply say that the PropertyDescriptor encapsulates information about one of the properties of a JavaBean (such as property name, property type, get, and set methods). The main methods are as follows:

  • GetName () : Gets the property name.
  • GetPropertyType () : Gets the property type.
  • GetReadMethod () : Gets the method used to read property values.
  • GetWriteMethod () : Gets the method used to write property values.
  • SetReadMethod (Method readMethod) : Sets the Method used to read property values.
  • SetWriteMethod (Method writeMethod) : Sets the Method used to write attribute values.
Person person = new Person(UUID.randomUUID().toString(), "Mr_nobody".18);
BeanInfo beanInfo = Introspector.getBeanInfo(Person.class);
PropertyDescriptor namePropertyDescriptor = new PropertyDescriptor("name", Person.class);
System.out.println("Attribute Name: + namePropertyDescriptor.getName());
System.out.println("Attribute Type: + namePropertyDescriptor.getPropertyType());

Method namePropertyDescriptorReadMethod = namePropertyDescriptor.getReadMethod();
Object personName = namePropertyDescriptorReadMethod.invoke(person, null);
System.out.println("before personName:" + personName);

Method namePropertyDescriptorWriteMethod = namePropertyDescriptor.getWriteMethod();
namePropertyDescriptorWriteMethod.invoke(person, "Tony");
personName = namePropertyDescriptorReadMethod.invoke(person, null);
System.out.println("after personName:" + personName);

// Output result:Attribute name: name Attribute type:class java.lang.String
before personName:Mr_nobody
after personName:Tony
Copy the code

4. Introduction to BeanDescriptor

Official introduction:

A BeanDescriptor provides global information about a “bean”, including its Java class, its displayName, etc.

This is one of the kinds of descriptor returned by a BeanInfo object, which also returns descriptors for properties, method, and events.

Java. Beans. BeanDescriptor, namely the object descriptor. It provides global information about a JavaBean, such as the JavaBean type, class name, and so on. It is one of the descriptors returned by the BeanInfo object, along with property descriptors, method descriptors, event descriptors, etc.

BeanInfo beanInfo = Introspector.getBeanInfo(Person.class);
BeanDescriptor beanDescriptor = beanInfo.getBeanDescriptor();
// BeanDescriptor beanDescriptor = new BeanDescriptor(Person.class);
System.out.println(beanDescriptor.getBeanClass());
System.out.println(beanDescriptor.getName());

// Output result:
class com.nobody.Person
Person
Copy the code

5. Case practice

In general, the ones that are used the most are Introspector, BeanInfo, and PropertyDescriptor, which are used in combination.

Requirement: Suppose we have a Person object that needs to be converted into a Map object. The Map is characterized by key-value pairs, so you need to traverse each attribute name and corresponding value of the Person object and put them into the Map.

package com.nobody;

import java.beans.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

/ * * *@Description
 * @Author Mr.nobody
 * @Date 2021/1/24
 * @Version1.0 * /
public class Demo {
    public static void main(String[] args) throws Exception {
        Person person = new Person(UUID.randomUUID().toString(), "Mr_nobody".18);
        System.out.println(beanToMap(person));

    }

    private static Map<String, Object> beanToMap(Object object)
            throws IntrospectionException, InvocationTargetException, IllegalAccessException {
        // Map to return
        Map<String, Object> map = new HashMap<>();
        // Get the BeanInfo object
        BeanInfo beanInfo = Introspector.getBeanInfo(object.getClass());
        // Get all attribute descriptors
        PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
        // Walk through each property descriptor
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            / / the property name
            String name = propertyDescriptor.getName();
            // Filter the class attribute
            if(! Objects.equals("class", name)) {
                // Get the property's get method
                Method readMethod = propertyDescriptor.getReadMethod();
                // Get the value of the attributeObject value = readMethod.invoke(object); map.put(name, value); }}returnmap; }}Copy the code
// Output the result
{name=Mr_nobody, id=57e496c6-87bb-4750-b176-5ef4bfb58b35, age=18}
Copy the code


What happens if we change the getId() method of the Person class to another name, or get rid of it? Suppose we change the getId() method name to getUid() and execute the above example.

public String getUid(a) {
    return id;
}
Copy the code
Exception in thread "main" java.lang.NullPointerException
	at com.nobody.Demo.beanToMap(Demo.java:38)
	at com.nobody.Demo.main(Demo.java:17)
Copy the code

The program reported an error, which is why THE JavaBean get and set methods follow certain rules.

The reason is simple: when we get the property descriptor for the id property, we get the property name, but because the get method doesn’t follow the rules, we can’t get the method by calling getReadMethod(), so we get a null pointer. Therefore, when using introspection and property descriptors, it is important to write the property get and set method names as standard, namely get + property name () and GET + property name ().