Java introspection (Introspector) and BeanUtils

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/dandandeshangni/article/details/86606232

The Bowl, anything for autumn sad painted fans.

width="750" height="350" src="http://www.merryyou.cn/mp4/java04.mp4" allowfullscreen="">

Outline

Introspection (Introspector) is the default Java language processing method for JavaBean class properties, events.

JavaBean is a special class, mainly used to transfer data, the method in this class is mainly used to access the private field, and method names meet certain naming conventions. If the transmission of information between the two modules, information may be encapsulated into a JavaBean, such an object is called "target value" (Value Object), or "VO." The method is relatively small. This information is stored in the private variable class, obtained by set (), get (). E.gUserInfo

package com.niocoder.test.introspector;

/**
 *
 */
 public class UserInfo {
     private String userName;
     private Integer age;
     private String webSite;

     public Integer getAge() {
         return age;
     }

     public void setAge(Integer age) {
         this.age = age;
     }

     public String getUserName() {
         return userName;
     }

     public void setUserName(String userName) {
         this.userName = userName;
     }

     public String getWebSite() {
         return webSite;
     }

     public void setWebSite(String webSite) {
         this.webSite = webSite;
     }
 }


There userName property in the UserInfo class, then we can get the value by getUserName, setUserName or set a new value. UserName attribute to access by getUserName / setUserName, this is the default rule. Java provides a getter / setter methods for accessing an attribute set of API's JDK, which is introspection.

JDK class library introspection:

PropertyDescriptor

PropertyDescriptor class represents a derived class attributes JavaBean memory. Main methods:

  1. getPropertyType (), get Class object attribute;
  2. getReadMethod (), a method for obtaining read the property value; getWriteMethod (), a method for obtaining the attribute value is written;
  3. hashCode (), get the object hash value;
  4. setReadMethod (Method readMethod), a method is provided for reading a property value;
  5. setWriteMethod (Method writeMethod), a method is provided for writing the attribute value.
package com.niocoder.test.introspector;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

public class BeanInfoUtil {
  /**
   * @param userInfo 实例
   * @param propertyName 属性名
   * @throws Exception
   */
  public static void setProperty(UserInfo userInfo, String propertyName) throws Exception {
      PropertyDescriptor propDesc = new PropertyDescriptor(propertyName, UserInfo.class);
      Method methodSetUserName = propDesc.getWriteMethod();
      methodSetUserName.invoke(userInfo, "郑龙飞");
      System.out.println("set userName:" + userInfo.getUserName());
  }

  /**
   * @param userInfo 实例
   * @param propertyName 属性名
   * @throws Exception
   */
  public static void getProperty(UserInfo userInfo, String propertyName) throws Exception {
      PropertyDescriptor proDescriptor = new PropertyDescriptor(propertyName, UserInfo.class);
      Method methodGetUserName = proDescriptor.getReadMethod();
      Object objUserName = methodGetUserName.invoke(userInfo);
      System.out.println("get userName:" + objUserName.toString());
  }
}

Introspector

The encapsulated JavaBean attributes operation. In the program as a JavaBean class, it is that call Introspector.getBeanInfo () method, the BeanInfo objects encapsulates obtained result information as JavaBean see this class, i.e., the attribute information.

of getPropertyDescriptors (), obtained as described properties, a method can be employed BeanInfo traverse, to locate, property class. Specific code as follows:

package com.niocoder.test.introspector;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

public class BeanInfoUtil {

  /**
    * @param userInfo 实例
    * @param propertyName 属性名
    * @throws Exception
    */
   public static void setPropertyByIntrospector(UserInfo userInfo, String propertyName) throws Exception {
       BeanInfo beanInfo = Introspector.getBeanInfo(UserInfo.class);
       PropertyDescriptor[] proDescrtptors = beanInfo.getPropertyDescriptors();
       if (proDescrtptors != null && proDescrtptors.length > 0) {
           for (PropertyDescriptor propDesc : proDescrtptors) {
               if (propDesc.getName().equals(propertyName)) {
                   Method methodSetUserName = propDesc.getWriteMethod();
                   methodSetUserName.invoke(userInfo, "niocoder");
                   System.out.println("set userName:" + userInfo.getUserName());
                   break;
               }
           }
       }
   }

   /**
    * @param userInfo 实例
    * @param propertyName 属性名
    * @throws Exception
    */
   public static void getPropertyByIntrospector(UserInfo userInfo, String propertyName) throws Exception {
       BeanInfo beanInfo = Introspector.getBeanInfo(UserInfo.class);
       PropertyDescriptor[] proDescrtptors = beanInfo.getPropertyDescriptors();
       if (proDescrtptors != null && proDescrtptors.length > 0) {
           for (PropertyDescriptor propDesc : proDescrtptors) {
               if (propDesc.getName().equals(propertyName)) {
                   Method methodGetUserName = propDesc.getReadMethod();
                   Object objUserName = methodGetUserName.invoke(userInfo);
                   System.out.println("get userName:" + objUserName.toString());
                   break;
               }
           }
       }
   }

}

By comparing these two classes can be seen, it is required to obtain PropertyDescriptor, just in a different way: by creating a direct access to the former object, which needs to traverse, so the use of PropertyDescriptor class more convenient.

Test

BeanInfoTest

public class BeanInfoTest {

    public static void main(String[] args) {
        UserInfo userInfo = new UserInfo();
        userInfo.setUserName("merryyou");
        try {
            BeanInfoUtil.getProperty(userInfo, "userName");

            BeanInfoUtil.setProperty(userInfo, "userName");

            BeanInfoUtil.getProperty(userInfo, "userName");

            BeanInfoUtil.setPropertyByIntrospector(userInfo, "userName");

            BeanInfoUtil.getPropertyByIntrospector(userInfo, "userName");

            BeanInfoUtil.setProperty(userInfo, "age");

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

Export

get userName:merryyou
set userName:郑龙飞
get userName:郑龙飞
set userName:niocoder
get userName:niocoder
Disconnected from the target VM, address: '127.0.0.1:65243', transport: 'socket'
java.lang.IllegalArgumentException: argument type mismatch
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.niocoder.test.introspector.BeanInfoUtil.setProperty(BeanInfoUtil.java:13)
	at com.niocoder.test.introspector.BeanInfoTest.main(BeanInfoTest.java:19)


Description: BeanInfoUtil.setProperty(userInfo, "age"); int data should be given to the age attribute type, and default value setProperty method which is assigned to the age attribute of type String. It will burst error message argument type mismatch parameter type mismatch.

BeanUtils

As can be seen from the above, the operation is very cumbersome introspection, the Apache is developed a simple, easy to operate API Toolkit --BeanUtils Bean attributes.

  • BeanUtils.getProperty(Object bean, String propertyName)
  • BeanUtils.setProperty(Object bean, String propertyName, Object value)

BeanUtilTest

public class BeanUtilTest {

    public static void main(String[] args) {

        UserInfo userInfo = new UserInfo();
        try {

            BeanUtils.setProperty(userInfo, "userName", "郑龙飞");
            System.out.println("set userName:" + userInfo.getUserName());
            System.out.println("get userName:" + BeanUtils.getProperty(userInfo, "userName"));

            BeanUtils.setProperty(userInfo, "age", 18);
            System.out.println("set age:" + userInfo.getAge());
            System.out.println("get age:" + BeanUtils.getProperty(userInfo, "age"));
            System.out.println("get userName type:" + BeanUtils.getProperty(userInfo, "userName").getClass().getName());
            System.out.println("get age type:" + BeanUtils.getProperty(userInfo, "age").getClass().getName());

            PropertyUtils.setProperty(userInfo, "age", 8);
            System.out.println(PropertyUtils.getProperty(userInfo, "age"));
            System.out.println(PropertyUtils.getProperty(userInfo, "age").getClass().getName());
            // 特殊 age属性为Integer类型
            PropertyUtils.setProperty(userInfo, "age", "8");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}

Export

set userName:郑龙飞
get userName:郑龙飞
set age:18
get age:18
get userName type:java.lang.String
get age type:java.lang.String
8
java.lang.Integer
Disconnected from the target VM, address: '127.0.0.1:50244', transport: 'socket'
Exception in thread "main" java.lang.IllegalArgumentException: Cannot invoke com.niocoder.test.introspector.UserInfo.setAge on bean class 'class com.niocoder.test.introspector.UserInfo' - argument type mismatch - had objects of type "java.lang.String" but expected signature "java.lang.Integer"
	at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:2195)
	at org.apache.commons.beanutils.PropertyUtilsBean.setSimpleProperty(PropertyUtilsBean.java:2108)
	at org.apache.commons.beanutils.PropertyUtilsBean.setNestedProperty(PropertyUtilsBean.java:1914)
	at org.apache.commons.beanutils.PropertyUtilsBean.setProperty(PropertyUtilsBean.java:2021)
	at org.apache.commons.beanutils.PropertyUtils.setProperty(PropertyUtils.java:896)
	at com.niocoder.test.introspector.BeanUtilTest.main(BeanUtilTest.java:28)
Caused by: java.lang.IllegalArgumentException: argument type mismatch
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:2127)
	... 5 more

Process finished with exit code 1

Download

Reference links

Guess you like

Origin blog.csdn.net/dandandeshangni/article/details/86606232
Recommended