Java中的Bean包中的几个类

值得注意的是一下几个类几乎都能通过代码直接写到Bean里面,但是这样的话就固定了BeanInfo,而以下几个类的巧妙之处就在于可以在不改动Bean本身属性的前提下动态的为Bean添加响应的属性。

BeanInfo把一个类看着一个标准Bean。可以获得各个属性的属性形容器来对Bean的属性进行操作。通过Introspector.getBeanInfo(Class<?> beanClass)来实例化
PropertyDescriptor属性形容器,包含着对Bean中属性的相关操作操作。可以通过BeanInfo.getBeanInfo获取或者通过new来实例化.

PropertyChangeListener属性改变监听事件,PropertyChangeSupport绑定Bean和监听器具体操作。通过实现propertyChange方法来自定义自己的操作。通过PropertyChangeSupport的firePropertyChange方法来触发所有监听事件,知道注意的是如果你要在Bean里面封装PropertyChangeSupport通过写方法暴露
监听器的addPropertyChangeListener方法时最好方法名还用addPropertyChangeListener,因为属性描述器的构造方法通过检查Bean里面是否有addPropertyChangeListener方法来判定是否支持绑定属性改变事件(isBound)。

VetoableChangeListener校验监听,有事件监听的使用方法相似,通过VetoableChangeSupport来绑定。通过实现vetoableChange方法来自定义自己的校验。VetoableChangeSupport提供了专门的PropertyVetoException来定义这个校验失败时间应该抛出异常。

实现PropertyEditor接口需要实现12个方法有时间显得过于复杂,可以通过通过继承PropertyEditorSupport并重写setValue或者getValue来是来自定义属性编辑器。

具体简单的使用见代码:

package BeanInfo;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyDescriptor;
import java.beans.PropertyEditor;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;

public class ListenerTest {
// 这些都是可以直接在set里面实现的,但是其独特之处在于动态设置,而不是写在set里面一经写成在代码运行过程中无法改变
    public static void main(String[] args) {
        TestEntity te1 = new TestEntity();
        te1.setName("1");
        // 为属性变动增加监听事件1
        te1.addPropertyChangeListener(new PropertyChangeListener() {

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                System.out.println(evt.getPropertyName() + "-oldVal:" + evt.getOldValue() + " newVal:" + evt.getNewValue());

            }
        });
        // 为属性变动增加监听事件1
        te1.addPropertyChangeListener(new PropertyChangeListener() {

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                System.out.println(evt.getPropertyName() + "开始改变");

            }
        });

        // 为属性变动增加验证事件1  一个专门的属性验证异常PropertyVetoException
        te1.addVetoableChangeListener(new VetoableChangeListener() {
            
            @Override
            public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException {
                if ("2".equals(evt.getNewValue())) {
                    throw new PropertyVetoException(evt.getPropertyName() + " canot is \"2\"", evt);
                }
                
            }
        });
        
        te1.getPropertyEditorSupport().addPropertyChangeListener(new PropertyChangeListener() {
                
                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    // 因为PropertyEditorSupport的触发机制,这里无法获得PropertyName,NewValue和OldValue
                    System.out.println(evt.getPropertyName() + evt.getNewValue() + evt.getOldValue() + "EDITOR");
                    
                }
            });

        te1.setName("2");   // 触发事件  TestEntity内部有属性编辑器,会自动做转换。
                            // 属性编辑器像是一个函数,setValue输入参数,getValue就得或者转换后的参数。
                            // 不过他作为一个类可以绑定到其他类上,通过继承PropertyEditorSupport并重写setValue或getValue方法来定义属于自己的编辑方式,
                            // 且setValue会触发PropertyEditorSupport的changeEvent,也就是说你可以为它绑定PropertyChangeListener(默认无法获得oldValue好newValue)。
                            // 来完成一个动静结合编辑器
        te1.setName("3");
        System.out.println(te1.getName());
        
        BeanInfo BeanInfo; // BeanInfo   把类看做一个Bean
        try {
            BeanInfo = Introspector.getBeanInfo(TestEntity.class);
            PropertyDescriptor pdName = new PropertyDescriptor("name", TestEntity.class);  // 构造一个属性描述器
            PropertyDescriptor[] pds = BeanInfo.getPropertyDescriptors();   // 获得一个bean的所以属性描述器
            System.out.println("isBound()-" + pdName.isBound());    // 是否支持绑定PropertyChangeListener
            System.out.println("isConstrained()-" + pdName.isConstrained()); // 是否绑定了VetoableChangeListener
            pdName.setPropertyEditorClass(TestPropertyEditorSupport.class); // 为这个属性描述器绑定属性编辑器class
            System.out.println("getPropertyEditorClass()-" + pdName.getPropertyEditorClass());  // 这个属性描述器上绑定的属性编辑器的Class
            System.out.println("getPropertyType()-" + pdName.getPropertyType()); // 这个属性的类型
            PropertyEditor pe = pdName.createPropertyEditor(te1);   // 获得这个属性描述器绑定的属性编辑器的实例化对象
            pe.setValue("BBB");
            System.out.println(pe.getValue());  // 属性编辑器getValue
            try {
                PropertyEditor pe2 = (PropertyEditor) new PropertyDescriptor("name", TestEntity.class).getPropertyEditorClass().newInstance();// 这里报空指针,说明属性编辑器只是绑定到属性描述器上了,而不是帮到到Bean的Class上了
              pe2.setValue("CCC");
              System.out.println(pe2.getValue());
            } catch (Exception e) {
                System.out.println("NO");
            }
            pdName.setValue("1", "2");
            pdName.getWriteMethod().invoke(te1, "4"); // 执行写方法
            System.out.println(te1.getName());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

辅助类:

package BeanInfo;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyEditorSupport;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
import java.beans.VetoableChangeSupport;

public class TestEntity {

    private String name;
    
    private PropertyChangeSupport listeners = new PropertyChangeSupport(this);
    
    private VetoableChangeSupport vetoableChangeListeners = new VetoableChangeSupport(this);
    
    private PropertyEditorSupport propertyEditorSupport = new TestPropertyEditorSupport(this);

    public String getName() {
        return name;
    }

    public void setName(String name) {
        listeners.firePropertyChange("name", this.name, name);
        try {
            vetoableChangeListeners.fireVetoableChange("name", this.name, name);
            propertyEditorSupport.setValue(name);
            this.name = (String) propertyEditorSupport.getValue();
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        }
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        listeners.removePropertyChangeListener(listener);
    }

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        listeners.addPropertyChangeListener(listener);
    }
    
    public void removeVetoableChangeListener(VetoableChangeListener listener) {
        vetoableChangeListeners.removeVetoableChangeListener(listener);
    }

    public void addVetoableChangeListener(VetoableChangeListener listener) {
        vetoableChangeListeners.addVetoableChangeListener(listener);
    }

    public PropertyEditorSupport getPropertyEditorSupport() {
        return propertyEditorSupport;
    }

    public void setPropertyEditorSupport(PropertyEditorSupport propertyEditorSupport) {
        this.propertyEditorSupport = propertyEditorSupport;
    }

    public PropertyChangeSupport getListeners() {
        return listeners;
    }

    public void setListeners(PropertyChangeSupport listeners) {
        this.listeners = listeners;
    }
}
package BeanInfo;

import java.beans.PropertyEditorSupport;

public class TestPropertyEditorSupport extends PropertyEditorSupport {
    

    public TestPropertyEditorSupport(Object testEntity) {
        super(testEntity);
    }

    @Override
    public void setValue(Object value) {
        super.setValue(String.valueOf(value) + "AAA");
    }
}

执行结果:

name-oldVal:1AAA newVal:2
name开始改变
java.beans.PropertyVetoException: name canot is "2"
	at BeanInfo.ListenerTest$3.vetoableChange(ListenerTest.java:42)
	at java.beans.VetoableChangeSupport.fireVetoableChange(VetoableChangeSupport.java:375)
	at java.beans.VetoableChangeSupport.fireVetoableChange(VetoableChangeSupport.java:271)
	at BeanInfo.TestEntity.setName(TestEntity.java:27)
	at BeanInfo.ListenerTest.main(ListenerTest.java:57)
name-oldVal:1AAA newVal:3
name开始改变
nullnullnullEDITOR
3AAA
isBound()-true
isConstrained()-false
getPropertyEditorClass()-class BeanInfo.TestPropertyEditorSupport
getPropertyType()-class java.lang.String
BBBAAA
NO
name-oldVal:3AAA newVal:4
name开始改变
nullnullnullEDITOR
4AAA

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yue_hu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值