Java's introspection mechanism & the principle of automatic injection

1. What is Java introspection:

◆Introspector in Java is a default processing method for properties, methods and events of JavaBean classes in Java. So, it may be difficult to understand, so to put it simply, it is a mechanism for Java to obtain the description of the JavaBean class through introspection, and to perform related operations on the JavaBean object.

◆ Do you think introspection and reflection are similar? Yes, there is indeed a connection. In fact, Java's introspection mechanism relies on reflection, which is equivalent to a kind of encapsulation of reflection. However, this method is only used to deal with JavaBean, which is more convenient for JavaBean processing.

 

2. Common classes using Java introspection

java.beans.Introspector: is a tool class that provides methods to obtain BeanInfo

        Common method: public static BeanInfo getBeanInfo( Class <?> beanClass)

                           throws IntrospectionException

java.beans.BeanInfo: is an interface, a Bean descriptor, used to obtain a collection of properties, methods and events.

        Common methods: MethodDescriptor [] getMethodDescriptors () ---- get an array of method descriptors

                        PropertyDescriptor [] getPropertyDescriptors ()------ Gets an array of property descriptors (most commonly used)

java.beans.PropertyDescriptor ; is a property descriptor, this class is used to get the property or get the readable or writable method of the property. That is, the setXXX() writable method and the getXXX() readable method
            Common method:
                            Construction method: PropertyDescriptor(String propertyName, Class<?> beanClass)
                           Common method: public Class <?> getPropertyType ()—gets the Class object of the property
                                            public Method  getReadMethod ()----Get the method to read the property value.
                                            public Method  getWriteMethod ()—The method to get the write property value.

3. Code testing

Create a JavaBean

public class Student {
	private String name;
	private String id;
	private Integer age;
	private String gender;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	public void setClass(Class clazz){//setClass, method is provided here, because the parent class has the getClass method
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", id=" + id + ", age=" + age + ", gender=" + gender + "]";
	}
}

 
3.2 Create a test class and test introspection
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

public class TestIntrospector {
	public static void main(String[] args)  {
		try {
			//The first way: get multiple attribute descriptors
			BeanInfo beanInfo = Introspector.getBeanInfo(Student.class);//获取BeanInfo
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();//Get property descriptors
			System.out.println(propertyDescriptors.length);//The length here is 5, not the 4 properties in the class class, because
			//All classes inherit the object class by default, and the object class contains the getClass method, so the attribute descriptor treats class as an attribute by default
			//But there is no setClass method, so the following array gets all the write methods, and a null pointer exception will be reported. If you want to use it, you need to manually provide the setClass method.
			for(PropertyDescriptor propertyDescriptor:propertyDescriptors){//traverse the property descriptor array to get each property descriptor
				Method read = propertyDescriptor.getReadMethod();//Get the read method,
				Method write = propertyDescriptor.getWriteMethod();//Get the write method
				System.out.println("Read method name: "+read.getName()+" Write method name: "+write.getName());
			}
			System.out.println("========================================================");
			//The second method: Get the specified property descriptor.
			PropertyDescriptor property = new PropertyDescriptor("name", Student.class);//Get the Student class name property descriptor
			Method nameRead = property.getReadMethod();//Get the property read method
			Method nameWrite = property.getWriteMethod();//Get the property write method
			System.out.println("Read method name: "+nameRead.getName()+" Write method name: "+nameWrite.getName());
		} catch (IntrospectionException e) {
			// TODO Auto-generated catch block
			System.out.println("There is no such JavaBen");
			e.printStackTrace ();
		}
	}
}

3.3. Running Results
5
Read method name: getAge Write method name: setAge
Read method name: getClass Write method name: setClass
Read method name: getGender Write method name: setGender
Read method name: getId Write method name: setId
Read method name: getName Write method name: setName
========================================================
Read method name: getName Write method name: setName

4. The principle of automatic injection

We all know that when using some front-end frameworks, such as Struts2, SpringMVC. These frameworks can instantiate the value of the JavaBean by introducing a JavaBean in .action or at the formal parameter of the controller method, and can obtain the data submitted by the form, so how does it get it?

In fact, request has a method, that is, request.getParameterMap(), which is to get all the key-value pairs sent by the form submission, but the framework is encapsulated inside, and then the framework uses introspection to encapsulate the data into JavaBeans.

Simulate this function and take a look at the automatic injection principle of the framework
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class BeanUtils {
	public static Object toBean(Class beanClass,Map form){
		 Set<Map.Entry<String, Object>> a = form.entrySet();//Convert map to set collection
		 Object javabean = null;
		 try {
			 javabean = beanClass.newInstance();//Get the instance object of JavaBen
			 //Encapsulate the data in the Map into JavaBen
			 if(form != null && form.size() > 0) {
		            for(Map.Entry<String,Object> entry :a) {
		                String propertyName = entry.getKey() ;
		                Object propertyValue = entry.getValue() ;
	                    PropertyDescriptor pd = new PropertyDescriptor(propertyName, beanClass) ;
	                    Method method = pd.getWriteMethod() ;
	                    method.invoke(javabean, propertyValue) ;//写入JavaBen
		            }
		        }
		} catch (Exception e1) {
			throw new RuntimeException(e1);
		}
		
		return javabean;
	}
	public static void main(String[] args) {
		Map<String,Object> form = new HashMap<String,Object>(); //Simulate a form
		form.put("name", "张三");
		form.put("id", "123");
		form.put("age", 20);
		form.put("gender", "女");
		Student stu1 = (Student) BeanUtils.toBean(Student.class, form);//Automatic injection
		System.out.println(stu1);
	}
}

output result
Student [name=Zhang San, id=123, age=20, gender=female]



Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325854240&siteId=291194637