JavaBean的自省

JavaBean的属性特点

事件

事件传播的语义

  1. 单播/广播(Unicast/Multicast)
  2. 同步传递(Synchronous delivery)
  3. 异常条件(Exceptional Conditions)
  4. 并发控制(Concurrency control)
  5. 传递过程修改监听器集合(Modification to the Set of Event Listeners during Event Delivery)

属性

  1. 访问者方法 (Setter,Getter)
  2. 索引属性
  3. 强迫属性(wish to be notified of the change)当属性变化时,强制更新并发送通知事件PropertyChangeListener
  4. 勉强属性(reject it if it is inappropriate)当属性变化不合理时,阻断属性更新,并且通知异常来说明必须在更新前进行校验

自省

内省器java.beans.Introspector

  1. Bean信息类 - java.beans.BeanInfo
  2. Bean描述符 - java.beans.BeanDescriptor
  3. Bean属性描述符 - java.beans.PropertyDescriptor
  4. Bean方法描述符 - java.beans.MethodDescriptor
  5. Bean事件集合描述符 - java.beans.EventSetDescriptor

自定义

  1. 属性修改器 - java.beans.PropertyEditor
  2. 属性修改器实现 - java.beans.PropertyEditorSupport
  3. 属性修改器管理器 - java.beans.PropertyEditorManager
  4. GUI组件自定义器 - java.beans.Customizer
    其中,Spring使用自己ConversionService转化

持久化

  1. 默认序列化实现 - 实现java.io.Serializable接口
  2. 选择性序列化实现 - 实现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"));
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值