Introspector in-depth understanding
Some concepts:
Introspector is a default processing method for JavaBean class attributes and events in the Java language.
JavaBean is a special class, mainly used to pass data information. The methods in this class are mainly used to access private fields, and the method name complies with certain naming rules. If information is passed between two modules, the information can be encapsulated into a JavaBean, which is called a "Value Object" or "VO". There are fewer methods. This information is stored in private variables of the class and obtained through set() and get().
For example, UserInfo class:
package ; public class UserInfo { private long userId; private String userName; private int age; private String emailAddress; public long getUserId() { return userId; } public void setUserId(long userId) { = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { = userName; } public int getAge() { return age; } public void setAge(int age) { = age; } public String getEmailAddress() { return emailAddress; } public void setEmailAddress(String emailAddress) { = emailAddress; } }
There is the attribute userName in the class UserInfo, then we can get its value or set a new value by gettingUserName and setUserName. Access the userName property through getUserName/setUserName, this is the default rule. The Java JDK provides a set of getter/setter methods used to access a certain attribute, which is introspection.
JDK introspection library:
PropertyDescriptor class:
The PropertyDescriptor class indicates that the JavaBean class exports a property through memory. Main methods:
1. getPropertyType() to obtain the Class object of the property;
2. getReadMethod(), obtain the method used to read attribute values; getWriteMethod(), obtain the method used to write attribute values;
3. hashCode(), get the hash value of the object;
4. setReadMethod(Method readMethod), set the method used to read attribute values;
5. setWriteMethod(Method writeMethod), set the method used to write attribute values.
The example code is as follows:
package ; import ; import ; import ; import ; public class BeanInfoUtil { public static void setProperty(UserInfo userInfo,String userName)throws Exception{ PropertyDescriptor propDesc=new PropertyDescriptor(userName,); Method methodSetUserName=(); (userInfo, "wong"); ("set userName:"+()); } public static void getProperty(UserInfo userInfo,String userName)throws Exception{ PropertyDescriptor proDescriptor =new PropertyDescriptor(userName,); Method methodGetUserName=(); Object objUserName=(userInfo); ("get userName:"+()); } }
Introspector class:
Encapsulate the properties in JavaBean for operation. When a program treats a class as a JavaBean, it means calling the() method. The resulting BeanInfo object encapsulates the result information used to treat this class as JavaBean, that is, the attribute information.
getPropertyDescriptors() to obtain the description of the property. You can use the method of traversing BeanInfo to find and set the properties of the class. The specific code is as follows:
package ; import ; import ; import ; import ; public class BeanInfoUtil { public static void setPropertyByIntrospector(UserInfo userInfo,String userName)throws Exception{ BeanInfo beanInfo=(); PropertyDescriptor[] proDescrtptors=(); if(proDescrtptors!=null&&>0){ for(PropertyDescriptor propDesc:proDescrtptors){ if(().equals(userName)){ Method methodSetUserName=(); (userInfo, "alan"); ("set userName:"+()); break; } } } } public static void getPropertyByIntrospector(UserInfo userInfo,String userName)throws Exception{ BeanInfo beanInfo=(); PropertyDescriptor[] proDescrtptors=(); if(proDescrtptors!=null&&>0){ for(PropertyDescriptor propDesc:proDescrtptors){ if(().equals(userName)){ Method methodGetUserName=(); Object objUserName=(userInfo); ("get userName:"+()); break; } } } } }
Through the comparison of these two classes, we can see that both of them need to obtain PropertyDescriptor, but the methods are different: the former is obtained directly by creating objects, while the latter requires traversal, so it is more convenient to use the PropertyDescriptor class.
Examples of usage:
package ; public class BeanInfoTest { /** * @param args */ public static void main(String[] args) { UserInfo userInfo=new UserInfo(); ("peida"); try { (userInfo, "userName"); (userInfo, "userName"); (userInfo, "userName"); (userInfo, "userName"); (userInfo, "userName"); (userInfo, "age"); } catch (Exception e) { // TODO Auto-generated catch block (); } } }
Output:
get userName:peida set userName:wong get userName:wong set userName:alan get userName:alan : argument type mismatch at .invoke0(Native Method) at (:39) at (:25) at (:597) at (:14) at (:22)
Description: (userInfo, "age"); The error reported is that the age property should be the int data type, and the value assigned to the age property by default in the setProperty method is String type. Therefore, an error message will be exposed that the argument type mismatch parameter type does not match.
BeanUtils Toolkit:
As can be seen from the above, introspection is very cumbersome, so Apache has developed a simple and easy-to-use API to operate the properties of Beans - the BeanUtils toolkit.
BeanUtils toolkit: Download: /beanutils/ Note: You also need a logging package /logging/ when applying
Use the BeanUtils toolkit to complete the above test code:
package ; import ; import ; import ; import ; public class BeanUtilTest { public static void main(String[] args) { UserInfo userInfo=new UserInfo(); try { (userInfo, "userName", "peida"); ("set userName:"+()); ("get userName:"+(userInfo, "userName")); (userInfo, "age", 18); ("set age:"+()); ("get age:"+(userInfo, "age")); ("get userName type:"+(userInfo, "userName").getClass().getName()); ("get age type:"+(userInfo, "age").getClass().getName()); (userInfo, "age", 8); ((userInfo, "age")); ((userInfo, "age").getClass().getName()); (userInfo, "age", "8"); } catch (IllegalAccessException e) { (); } catch (InvocationTargetException e) { (); } catch (NoSuchMethodException e) { (); } } }
Running results:
set userName:peida get userName:peida set age:18 get age:18 get userName type: get age type: 8 Exception in thread "main" : Cannot invoke on bean class 'class ' - argument type mismatch - had objects of type "" but expected signature "int" at (:2235) at (:2151) at (:1957) at (:2064) at (:858) at (:38) Caused by: : argument type mismatch at .invoke0(Native Method) at (:39) at (:25) at (:597) at (:2170) ... 5 more
illustrate:
1. Get the value of the property, for example, (userInfo,"userName"), return the string
2. Set the value of the property, for example, (userInfo,"age", 8), the parameter is automatically wrapped by a string or a basic type. The value of the set attribute is a string, and the obtained value is also a string, not a basic type. Features:
1). Operation on properties of basic data types: During WEB development and use, the values will be converted into strings when entered and displayed, but the underlying operation uses basic types. These types transfer actions are automatically completed by BeanUtils.
2). Operation on attributes that reference data types: First of all, there must be objects in the class, not null, for example, private Date birthday=new Date();. It operates on the properties of the object rather than the entire object, for example, (userInfo,"",111111);
package ; import ; public class UserInfo { private Date birthday = new Date(); public void setBirthday(Date birthday) { = birthday; } public Date getBirthday() { return birthday; } }
package ; import ; import ; import ; public class BeanUtilTest { public static void main(String[] args) { UserInfo userInfo=new UserInfo(); try { (userInfo, "","111111"); Object obj = (userInfo, ""); (obj); } catch (IllegalAccessException e) { (); } catch (InvocationTargetException e) { (); } catch (NoSuchMethodException e) { (); } } }
The difference between class and BeanUtils is that when running getProperty and setProperty operations, there is no type conversion, and the original type or wrapper class of the property is used. Since the data type of the age attribute is int, the method (userInfo, "age", "8") will reveal that the data type does not match and the value cannot be assigned to the attribute.
Thank you for reading, I hope it can help you. Thank you for your support for this site!