小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

spring中 EventPublisher

 印度阿三17 2019-04-10

作用

這個(gè)其實(shí)就是一個(gè)設(shè)計(jì)模式中的觀察者模式,廣播推送消息

spring中怎么用?

  1. 客戶端發(fā)布事件
public class IOCTest_Ext {
	
	@Test
	public void test01(){
		AnnotationConfigApplicationContext applicationContext  = new AnnotationConfigApplicationContext(ExtConfig.class);
		
		
		//發(fā)布事件;
		applicationContext.publishEvent(new ApplicationEvent(new String("我發(fā)布的時(shí)間")) {
		});
		
		applicationContext.close();
	}

}
  1. listen監(jiān)聽事件
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {

	//當(dāng)容器中發(fā)布此事件以后,方法觸發(fā)
	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		// TODO Auto-generated method stub
		System.out.println("收到事件:" event);
	}

}
  1. 結(jié)果
收到事件:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@6d86b085: startup date [Wed Apr 10 06:59:46 CST 2019]; root of context hierarchy]
收到事件:com.atguigu.test.IOCTest_Ext$1[source=我發(fā)布的時(shí)間]
收到事件:org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@6d86b085: startup date [Wed Apr 10 06:59:46 CST 2019]; root of context hierarchy]

有三個(gè)結(jié)果:分別是容器刷新、關(guān)閉的事件,還有一個(gè)是我們自定義的。

  1. 也可以使用更方便的注解的方式,效果是一樣的
@Service
public class UserService {
	
	@EventListener(classes={ApplicationEvent.class})
	public void listen(ApplicationEvent event){
		System.out.println("UserService。。監(jiān)聽到的事件:" event);
	}

}

  1. 結(jié)果
UserService。。監(jiān)聽到的事件:org.springframework.context.event.ContextRefreshedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@6d86b085: startup date [Wed Apr 10 07:01:54 CST 2019]; root of context hierarchy]
UserService。。監(jiān)聽到的事件:com.atguigu.test.IOCTest_Ext$1[source=我發(fā)布的時(shí)間]
UserService。。監(jiān)聽到的事件:org.springframework.context.event.ContextClosedEvent[source=org.springframework.context.annotation.AnnotationConfigApplicationContext@6d86b085: startup date [Wed Apr 10 07:01:54 CST 2019]; root of context hierarchy]

源碼分析

applicationContext.publishEvent(new ApplicationEvent(new String(“我發(fā)布的時(shí)間”)) {});
AbstractApplicationContext#publishEvent

this.getApplicationEventMulticaster().multicastEvent((ApplicationEvent)applicationEvent, eventType);

如果發(fā)現(xiàn)有任務(wù)執(zhí)行器,就交給它處理,沒有的話就直接處理。默認(rèn)情況下是沒有的

public void multicastEvent(final ApplicationEvent event, ResolvableType eventType) {
        ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event);
        //得到容器中所有的listener
        Iterator var4 = this.getApplicationListeners(event, type).iterator();

        while(var4.hasNext()) {
            final ApplicationListener<?> listener = (ApplicationListener)var4.next();
            Executor executor = this.getTaskExecutor();
            if (executor != null) {
                executor.execute(new Runnable() {
                    public void run() {
                        SimpleApplicationEventMulticaster.this.invokeListener(listener, event);
                    }
                });
            } else {
                this.invokeListener(listener, event);
            }
        }

    }
 private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
        try {
            listener.onApplicationEvent(event);

問(wèn)題:這些listen是什么時(shí)候注入的呢?
org.springframework.context.event.AbstractApplicationEventMulticaster#retrieveApplicationListeners

private Collection<ApplicationListener<?>> retrieveApplicationListeners(
			ResolvableType eventType, Class<?> sourceType, ListenerRetriever retriever) {

		LinkedList<ApplicationListener<?>> allListeners = new LinkedList<ApplicationListener<?>>();
		//1.所有實(shí)現(xiàn)ApplicationListener或者加@EventListener并且在容器中的都會(huì)自動(dòng)注入進(jìn)來(lái)
		Set<ApplicationListener<?>> listeners;
		Set<String> listenerBeans;
		synchronized (this.retrievalMutex) {
			listeners = new LinkedHashSet<ApplicationListener<?>>(this.defaultRetriever.applicationListeners);
			listenerBeans = new LinkedHashSet<String>(this.defaultRetriever.applicationListenerBeans);
		}
		//處理ApplicationListener這種類型的,都加入到listeners中
		for (ApplicationListener<?> listener : listeners) {
			if (supportsEvent(listener, eventType, sourceType)) {
				if (retriever != null) {
					retriever.applicationListeners.add(listener);
				}
				allListeners.add(listener);
			}
		}
		if (!listenerBeans.isEmpty()) {
			BeanFactory beanFactory = getBeanFactory();
			for (String listenerBeanName : listenerBeans) {
				try {
					Class<?> listenerType = beanFactory.getType(listenerBeanName);
					if (listenerType == null || supportsEvent(listenerType, eventType)) {
						ApplicationListener<?> listener =
								beanFactory.getBean(listenerBeanName, ApplicationListener.class);
						if (!allListeners.contains(listener) && supportsEvent(listener, eventType, sourceType)) {
							if (retriever != null) {
								retriever.applicationListenerBeans.add(listenerBeanName);
							}
							allListeners.add(listener);
						}
					}
				}
				catch (NoSuchBeanDefinitionException ex) {
					// Singleton listener instance (without backing bean definition) disappeared -
					// probably in the middle of the destruction phase
				}
			}
		}
		//2.排序
		AnnotationAwareOrderComparator.sort(allListeners);
		return allListeners;
	}

查看這個(gè)方法 this.getApplicationListeners(event, type)

擴(kuò)展

  1. 異步方式來(lái)處理
    2
來(lái)源:http://www./content-4-160251.html

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多