zoukankan      html  css  js  c++  java
  • spring事件监听机制

      事件机制的主要成员:  

    1. 事件
    2. 事件监听器(监听事件触发,处理一些事情)
    3. 事件源(发布事件)

    javaSE 提供了一系列自定义事件的标准。

    EvenObject,为javaSE提供的事件类型基类,任何自定义事件都必须继承它。

    EventListener,为javaSE提供的事件监听器基类,任何自定义事件监听器都得实现。

    javaSE未提供事件发布者,由各个应用程序自行实现事件发布者这一角色。

    spring提供了ApplicationEventPublisher接口作为事件发布者,并且ApplicationContext接口继承了该接口,担当着事件发布者的角色。但ApplicationContext接口的具体实现各有差异。

    spring提供了ApplicationEventMulticaster接口,负责管理ApplicationListener和发布ApplicationEvent。ApplicationContext接口会把事件的相关工作委托给ApplicationEventMulticaster的实现类做,

     

    spring事件机制流程:

    • ApplicationContext发布事件 
    //发布事件
    context.publishEvent(event);
    

      实际上是由ApplicationContext的实现AbstractApplicationContext执行发布事件的行为

    • 找到事件广播器,广播事件
    getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
    • 执行SimpleApplicationEventMulticaster中的multicastEvent方法,调用事件监听器的onApplicationEvent()方法
    	@Override
    	public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
    		ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
    		for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
    			Executor executor = getTaskExecutor();
    			if (executor != null) {
    				executor.execute(new Runnable() {
    					@Override
    					public void run() {
    						invokeListener(listener, event);
    					}
    				});
    			}
    			else {
    				invokeListener(listener, event);
    			}
    		}
    	}
    

      

    	protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
    		ErrorHandler errorHandler = getErrorHandler();
    		if (errorHandler != null) {
    			try {
    				doInvokeListener(listener, event);
    			}
    			catch (Throwable err) {
    				errorHandler.handleError(err);
    			}
    		}
    		else {
    			doInvokeListener(listener, event);
    		}
    	}
    
    	@SuppressWarnings({"unchecked", "rawtypes"})
    	private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
    		try {
    			listener.onApplicationEvent(event);
    		}
    		catch (ClassCastException ex) {
    			String msg = ex.getMessage();
    			if (msg == null || matchesClassCastMessage(msg, event.getClass().getName())) {
    				// Possibly a lambda-defined listener which we could not resolve the generic event type for
    				// -> let's suppress the exception and just log a debug message.
    				Log logger = LogFactory.getLog(getClass());
    				if (logger.isDebugEnabled()) {
    					logger.debug("Non-matching event type for listener: " + listener, ex);
    				}
    			}
    			else {
    				throw ex;
    			}
    		}
    	}
    

      

    自定义事件Demo

    • 自定义事件

        

    package com.spring.event.event;
    
    import org.springframework.context.ApplicationEvent;
    
    import com.spring.event.bean.Notify;
    
    /**
     * 自定义事件
     * @author sxq
     * @time 2018年8月31日 上午10:26:24
     *
     */
    public class NotifyEvent extends ApplicationEvent {
    
    	private int version;
    	
    	private Notify notify;
    	public int getVersion() {
    		return version;
    	}
    
    	public void setVersion(int version) {
    		this.version = version;
    	}
    
    	/**
    	 * serialVersionUID
    	 */
    	private static final long serialVersionUID = -6198589267233914254L;
    
    	public NotifyEvent(Object source) {
    		super(source);
    		
    	}
    	public Notify getNotify() {
    		return notify;
    	}
    
    	public void setNotify(Notify notify) {
    		this.notify = notify;
    	}
    
    	public NotifyEvent(Object source,Notify notify) {
    		this(source);
    		this.notify = notify;
    		
    	}
    
    }
    

      

    • 自定义监听器
    package com.spring.event.listner;
    
    import org.springframework.context.ApplicationListener;
    import org.springframework.stereotype.Component;
    
    import com.spring.event.event.NotifyEvent;
    
    /**
     * 自定义监听器
     * @author sxq
     * @time 2018年8月31日 上午10:27:04
     *
     */
    @Component
    public class NotifyListenr implements ApplicationListener<NotifyEvent>{
    
    	@Override
    	public void onApplicationEvent(NotifyEvent event) {
    		
    		System.out.println(event.getNotify().toString());
    		
    		//监听事件后,处理后续事情
    	}
    
    }
    

      

    • 发布
    	ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
    	Notify notify = new Notify("李四",21);
    	NotifyEvent event = new NotifyEvent("NotifyEvent",notify);
    	event.setVersion(100);	
    	//发布事件
         context.publishEvent(event);
    

      

  • 相关阅读:
    富文本,NSAttributedString,当需要改变的内容有相同的时候的解决方法
    iOS 如何将证书和描述文件给其他人进行真机调试(Provisioning profile "描述文件的名字" doesn't include the currently selected device "你的手机名字".)
    iOS 去除字符串中的H5标签
    The dependency `AMapSearch (~> 3.0.0)` is not used in any concrete target. cocoapods在update或者install的时候报错解决办法
    iOS 3D Touch 五个快捷键的问题
    根据内容计算cell的高度
    iOS UIPickerView 可能会出现选中行不显示或者去掉上下两条横线的问题解决,
    iOS 开发 常用的正则验证表达式:电话 、邮箱等等
    使用MLeaksFinder检测项目中的内存泄露
    iOS 当请求到的数据是double类型,会失去精准度,并且去掉小数点后的0
  • 原文地址:https://www.cnblogs.com/sxqjava/p/9568641.html
Copyright © 2011-2022 走看看