preface

Java.beans is a package that deals with Java beans. There are 26 classes in JDK 8, but there are few that are remotely useful. Similar functionality could be addressed in a better way.

But there are a few classes in there that seem to be useful.

BeanDescriptor

“BeanDescriptor”, “BeanDescriptor”, “BeanDescriptor”, “BeanDescriptor”, “BeanDescriptor”, “BeanDescriptor”

There are only a few set/get bean names in there. The default request, getDisplayName, returns the class name passed in, and, more mysteriously, the getValue, setValue, and attributeNames methods are operations on a map.

Using BeanDescriptor alone doesn’t seem to work either. It should be wrapped in some cases.

PropertyDescriptor

For example, the bean has a field of type String value, which can be used to obtain the Method of set/get.

public class MyBean {
    private String value="s";
    public String getValue(a) {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
    @Override
    public String toString(a) {
        return "MyBean{" +
                "value='" + value + ' ''+'}'; }}Copy the code

 try {
     MyBean myBean = new MyBean();
     PropertyDescriptor value = new PropertyDescriptor("value", MyBean.class);
     Method writeMethod = value.getWriteMethod();
     writeMethod.invoke(myBean, "Zhang");
     System.out.println(myBean);
 } catch (IntrospectionException | IllegalAccessException | InvocationTargetException e) {
     e.printStackTrace();
 }
 
Copy the code

Finally, there is a fun feature that I vaguely think has potential. It allows you to process fields when you get/set. It can also be considered a proxy, but it’s a little different from a proxy.

After you get the description of the specified field through the PropertyDescriptor, you set up a “factory” class to it, which inherits the PropertyEditor, and must override its parameter constructor, and then create an instance of that class with createPropertyEditor, His argument is an instance of the target bean.

However, the changed data is not reflected in the final bean. Although I was given a notification interface for property changes, I expected old data and new data to be passed in. In fact, null is passed in all the data in the source code.

If you change the final bean to reflect, you have to write it yourself via reflection.

public class Main {
    public static class MyStringEditor extends PropertyEditorSupport {
        public MyStringEditor(Object source) {
            super(source);
        }

        @Override
        public void setValue(Object value) {
            PropertyDescriptor propertyDescriptor = null;
            try {
                propertyDescriptor = new PropertyDescriptor("value", MyBean.class);
                propertyDescriptor.getWriteMethod().invoke(getSource(), value);

            } catch(IntrospectionException | IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); }}@Override
        public void setAsText(String text) throws IllegalArgumentException {
            super.setAsText(text);
        }

        @Override
        public Object getValue(a) {
            return "New value"+ getSource(); }}public static void main(String[] args) throws IOException {

        try {
            MyBean myBean = new MyBean();
            PropertyDescriptor value = new PropertyDescriptor("value", MyBean.class);
            value.setPropertyEditorClass(MyStringEditor.class);
            PropertyEditor propertyEditor = value.createPropertyEditor(myBean);
            propertyEditor.addPropertyChangeListener(new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    System.out.println("Data changes"+ evt.getSource()); }}); propertyEditor.setValue(new String("test"));
            System.out.println(myBean.getValue());
        } catch(IntrospectionException e) { e.printStackTrace(); }}}Copy the code

  try {
      BeanInfo beanInfo = Introspector.getBeanInfo(MyBean.class);
      PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
      for(PropertyDescriptor propertyDescriptor : propertyDescriptors) { System.out.println(propertyDescriptor.getName()); }}catch (IntrospectionException e) {
      e.printStackTrace();
  }
Copy the code

Introspector

This class is a utility class that gets information about the target bean, such as all public methods, and all fields that conform to the Java Bean specification.

BeanDescriptor’s information is also available.

 try {
     BeanInfo beanInfo = Introspector.getBeanInfo(MyBean.class);
     PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
     MethodDescriptor[] methodDescriptors = beanInfo.getMethodDescriptors();
     for (MethodDescriptor methodDescriptor : methodDescriptors) {
         System.out.println(methodDescriptor.getName() +""+methodDescriptor);
     }
     for(PropertyDescriptor propertyDescriptor : propertyDescriptors) { System.out.println(propertyDescriptor.getName()); }}catch (IntrospectionException e) {
     e.printStackTrace();
 }
Copy the code