JavaBean的属性特点
事件
事件传播的语义
- 单播/广播(Unicast/Multicast)
- 同步传递(Synchronous delivery)
- 异常条件(Exceptional Conditions)
- 并发控制(Concurrency control)
- 传递过程修改监听器集合(Modification to the Set of Event Listeners during Event Delivery)
属性
- 访问者方法 (Setter,Getter)
- 索引属性
- 强迫属性(wish to be notified of the change)当属性变化时,强制更新并发送通知事件PropertyChangeListener
- 勉强属性(reject it if it is inappropriate)当属性变化不合理时,阻断属性更新,并且通知异常来说明必须在更新前进行校验
自省
内省器java.beans.Introspector
- Bean信息类 - java.beans.BeanInfo
- Bean描述符 - java.beans.BeanDescriptor
- Bean属性描述符 - java.beans.PropertyDescriptor
- Bean方法描述符 - java.beans.MethodDescriptor
- Bean事件集合描述符 - java.beans.EventSetDescriptor
自定义
- 属性修改器 - java.beans.PropertyEditor
- 属性修改器实现 - java.beans.PropertyEditorSupport
- 属性修改器管理器 - java.beans.PropertyEditorManager
- GUI组件自定义器 - java.beans.Customizer
其中,Spring使用自己ConversionService转化
持久化
- 默认序列化实现 - 实现java.io.Serializable接口
- 选择性序列化实现 - 实现writeObject和readObject方法
自定义序列化实现 - java.io.externalizable接口
测试代码
首先定义一个person
类
public class Person implements Serializable{
private Long id;
private String name;
private intage;
private Date updateTime;
private final transient PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
public Long getId(){
return id;
}
public void setId(Long id){
this.id=id;
}
public String getName(){
return name;
}
public void setName(String name){
this.name=name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age=age;
}
public Date getUpdateTime(){
return updateTime;
}
public void setUpdateTime(Date updateTime){
this.updateTime=updateTime;
}
}
然后编写一个Main方法进行测试
public static void main(String[]args)throws Exception{
//其中Introspector.getBeanInfo()方法表示内省到什么类为止
BeanInfo beanInfo = Introspector.getBeanInfo(Person.class,Object.class);
System.out.println(beanInfo.getBeanDescriptor());
System.out.println(Arrays.toString(beanInfo.getEventSetDescriptors()));
System.out.println(Arrays.toString(beanInfo.getMethodDescriptors()));
System.out.println(Arrays.toString(beanInfo.getPropertyDescriptors()));
}
输出结果:
===============
java.beans.BeanDescriptor[name=Person; beanClass=class scan.introspectionDemo.Person]
===============
[]
===============
[java.beans.MethodDescriptor[name=getName; method=public java.lang.String scan.introspectionDemo.Person.getName()], java.beans.MethodDescriptor[name=setId; method=public void scan.introspectionDemo.Person.setId(java.lang.Long)], java.beans.MethodDescriptor[name=getUpdateTime; method=public java.util.Date scan.introspectionDemo.Person.getUpdateTime()], java.beans.MethodDescriptor[name=setAge; method=public void scan.introspectionDemo.Person.setAge(int)], java.beans.MethodDescriptor[name=setName; method=public void scan.introspectionDemo.Person.setName(java.lang.String)], java.beans.MethodDescriptor[name=getAge; method=public int scan.introspectionDemo.Person.getAge()], java.beans.MethodDescriptor[name=getId; method=public java.lang.Long scan.introspectionDemo.Person.getId()], java.beans.MethodDescriptor[name=setUpdateTime; method=public void scan.introspectionDemo.Person.setUpdateTime(java.util.Date)]]
======================================================
[java.beans.PropertyDescriptor[name=age; values={expert=false; visualUpdate=false; hidden=false; enumerationValues=[Ljava.lang.Object;@3e6fa38a; required=false}; propertyType=int; readMethod=public int scan.introspectionDemo.Person.getAge(); writeMethod=public void scan.introspectionDemo.Person.setAge(int)], java.beans.PropertyDescriptor[name=id; values={expert=false; visualUpdate=false; hidden=false; enumerationValues=[Ljava.lang.Object;@66a3ffec; required=false}; propertyType=class java.lang.Long; readMethod=public java.lang.Long scan.introspectionDemo.Person.getId(); writeMethod=public void scan.introspectionDemo.Person.setId(java.lang.Long)], java.beans.PropertyDescriptor[name=name; values={expert=false; visualUpdate=false; hidden=false; enumerationValues=[Ljava.lang.Object;@77caeb3e; required=false}; propertyType=class java.lang.String; readMethod=public java.lang.String scan.introspectionDemo.Person.getName(); writeMethod=public void scan.introspectionDemo.Person.setName(java.lang.String)], java.beans.PropertyDescriptor[name=updateTime; values={expert=false; visualUpdate=false; hidden=false; enumerationValues=[Ljava.lang.Object;@1e88b3c; required=false}; propertyType=class java.util.Date; readMethod=public java.util.Date scan.introspectionDemo.Person.getUpdateTime(); writeMethod=public void scan.introspectionDemo.Person.setUpdateTime(java.util.Date)]]
测试JavaBean的事件监听
首先定义事件监听的实体内容类:
public class ApplicationEvent extends EventObject{
private final long timestamp;
/**
*Constructs a prototypical Event.
*
*@param source the object on which the Event initially occurred
*@throws IllegalArgumentException if source is null
*/
public ApplicationEvent(Object source){
super(source);
this.timestamp = System.currentTimeMillis();
}
public long getTimestamp(){
return timestamp;
}
@Override
public String toString(){
return "ApplicationEvent{"+
"timestamp = "+timestamp+
",source="+source+
'}';
}
}
抽象事件监听:
public interface ApplicationEventListener<E extends ApplicationEvent>extends EventListener{
void onEvent(E event);
}
抽象事件的注册:
public interface ApplicationEventListenerRegistry{
//根据JavaBean的规范,需要声明一个事件监听添加的方法,以及移除的方法
void addApplicationEventListener(ApplicationEventListener<?> listener);
void removeApplicationEventListener(ApplicationEventListener<?> listener);
ApplicationEvent Listener[] getApplicationEventListeners();
ApplicationEvent Listener[] getApplicationEventListeners(Class<? extends ApplicationEvent> eventType);
}
实现事件的注册:
public class GenericApplicationEventListenerRegistry implements ApplicationEventListenerRegistry{
private Map<String,List<ApplicationEventListener<?>>> typedListeners = new LinkedHashMap<>();
@Override
public void addApplicationEventListener(ApplicationEventListener<?> listener){
List<ApplicationEventListener<?>> listeners = getListeners(listener);
listeners.add(listener);
}
@Override
public void removeApplicationEventListener(ApplicationEventListener<?> listener){
List<ApplicationEventListener<?>> listeners = getListeners(listener);
listeners.remove(listener);
}
@Override
public ApplicationEventListener[] getApplicationEventListeners(){
return new ApplicationEventListener[0];
}
@Override
public ApplicationEventListener[] getApplicationEventListeners(Class<? extends ApplicationEvent> eventType){
String eventTypeName = eventType.getTypeName();
return typedListeners.getOrDefault(eventTypeName,Collections.emptyList()).toArray(new ApplicationEventListener[0]);
}
static class ApplicationEventListenerComparator implements Comparator<ApplicationEventListener>{
@Override
public int compare(ApplicationEventListener o1,ApplicationEventListener o2){
String oneClassName = o1.getClass().getName();
String anotherClassName = o2.getClass().getName();
return oneClassName.compareTo(anotherClassName);
}
}
protected List<ApplicationEventListener<?>> getListeners(ApplicationEventListener<?> listener){
Class<?> listenerClass = listener.getClass();
Type[] genericInterfaces = listenerClass.getGenericInterfaces();
String eventTypeName = Stream.of(genericInterfaces)
.filter(t->t instanceof ParameterizedType)//判断接口是否ParameterizedType类型
.map(t->(ParameterizedType)t)//转换为ParameterizedType
//判断ApplicationEventListener原始类型是否
.filter(parameterizedType->ApplicationEventListener.class.equals(parameterizedType.getRawType()))
.map(parameterizedType->{
//获取第一个泛型参数
return parameterizedType.getActualTypeArguments()[0].getTypeName();
})
.findFirst()
.orElse(null);
return typedListeners.computeIfAbsent(eventTypeName,k->new LinkedList<>());
}
}
定义事件类:
public class MyEvent extends ApplicationEvent{
/**
*Constructs a prototypical Event.
*
*@param source the object on which the Event initially occurred
*@throws IllegalArgumentException if source is null
*/
public MyEvent(Object source){
super(source);
}
}
定义事件一:
public class MyEventListener implements ApplicationEventListener<MyEvent>{
@Override
public void onEvent(MyEvent event){
System.out.println("MyEventListener处理事件:"+event);
}
}
定义事件二:
public class MyEventListener2 implements ApplicationEventListener<MyEvent>{
@Override
public void onEvent(MyEvent event){
System.err.println("MyEventListener2处理事件:"+event);
}
}
事件发布:
public class ApplicationEventMulticaster{
private final ApplicationEventListenerRegistry registry;
public ApplicationEventMulticaster(){
this.registry=new SimpleApplicationEventListenerRegistry();
}
public ApplicationEventMulticaster(ApplicationEventListenerRegistry registry){
this.registry=registry;
}
publicvoidaddApplicationEventListener(ApplicationEventListener<?> listener){
registry.addApplicationEventListener(listener);
}
publicvoidremoveApplicationEventListener(ApplicationEventListener<?> listener){
registry.removeApplicationEventListener(listener);
}
public ApplicationEventListener[] getApplicationEventListeners(){
return registry.getApplicationEventListeners();
}
public ApplicationEventListener[] getApplicationEventListeners(Class<? extends ApplicationEvent> eventType){
return registry.getApplicationEventListeners(eventType);
}
public void multicastEvent(ApplicationEvent event){
//逐一传递
Class<? extends ApplicationEvent> eventType = event.getClass();
for(ApplicationEventListener listener : getApplicationEventListeners(eventType)){
listener.onEvent(event);
}
}
public static void main(String[] args){
//displaySimpleEvent();
displayGenericEvent();
}
private static void displayGenericEvent(){
ApplicationEventMulticaster multicaster=
new ApplicationEventMulticaster(new GenericApplicationEventListenerRegistry());
multicaster.addApplicationEventListener(new MyEventListener());
multicaster.addApplicationEventListener(new MyEventListener2());
//传播的是ApplicationEvent,MyEventListener需要MyEvent类型,属于前者子类
multicaster.multicastEvent(new MyEvent("2019"));
multicaster.multicastEvent(new MyEvent2("2000"));
}
private static void displaySimpleEvent(){
ApplicationEventMulticaster multicaster=
new ApplicationEventMulticaster();
//注册一个事件监听器
multicaster.addApplicationEventListener(event->{
System.out.println("处理事件-1:"+event);
});
multicaster.addApplicationEventListener(event->{
System.out.println("处理事件-2:"+event);
});
multicaster.addApplicationEventListener(event->{
System.out.println("处理事件-3:"+event);
});
//广播事件
multicaster.multicastEvent(new ApplicationEvent("Hello,World"));
}
}