中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Springboot中AbstractApplicationEventMulticaster有什么作用

發布時間:2021-11-17 10:05:38 來源:億速云 閱讀:113 作者:iii 欄目:大數據

本篇內容介紹了“Springboot中AbstractApplicationEventMulticaster有什么作用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

    Springboot的版本2.0.9.release,對應的SpringFramework值5.0.x.release。

    AbstractApplicationEventMulticaster并不是Springboot里面的,而是屬于SpringFramework的。

                  Springboot中AbstractApplicationEventMulticaster有什么作用

                                                                                      圖1

    如上圖1所示,AbstractApplicationEventMulticaster繼承了BeanFactoryAware,用于獲取BeanFactory;ApplicationEventMulticaster則包含增加、刪除ApplicationListener的接口方法,支持對象和String類型的bean名稱。

    一開始以為AbstractApplicationEventMulticaster應該有個List<ApplicationListener>的屬性用于存放加入其中的ApplicationListener,但是看了源碼之后,發現Spring考慮的更周全、考慮的情況更多。

    List-1

public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {
    private final AbstractApplicationEventMulticaster.ListenerRetriever defaultRetriever = new AbstractApplicationEventMulticaster.ListenerRetriever(false);
    final Map<AbstractApplicationEventMulticaster.ListenerCacheKey, AbstractApplicationEventMulticaster.ListenerRetriever> retrieverCache = new ConcurrentHashMap(64);
    @Nullable
    private ClassLoader beanClassLoader;
    @Nullable
    private BeanFactory beanFactory;
    private Object retrievalMutex;

...
private class ListenerRetriever {
    public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet();
    public final Set<String> applicationListenerBeans = new LinkedHashSet();
    private final boolean preFiltered;

    public ListenerRetriever(boolean preFiltered) {
        this.preFiltered = preFiltered;
    }
...

    如上的List-1,ListenerRetriever中的LinkedHashSet,才是真正存放ApplicationListener的地方。而retrieverCache則是用于作為緩存,為什么要做緩存,是因為我們丟給AbstractApplicationEventMulticaster的Event不一定會被發送,只有找到能支持這種Event的ApplicationListener才會進行發送。

    首先來看下addApplicationListener,如下List-2,如果是ApplicationListener的實例,則加入到defaultRetriever的Set中,如果是String類型的beanName,則加入到defaultRetriever的applicationListenerBeans中,最后都調用retrieverCache的clear方法,retrieverCache是個線程安全的Map,因為新加入了ApplicationListener,所以我們需要更新我們的緩存。

    List-2

public void addApplicationListener(ApplicationListener<?> listener) {
    synchronized(this.retrievalMutex) {
        Object singletonTarget = AopProxyUtils.getSingletonTarget(listener);
        if (singletonTarget instanceof ApplicationListener) {
            this.defaultRetriever.applicationListeners.remove(singletonTarget);
        }

        this.defaultRetriever.applicationListeners.add(listener);
        this.retrieverCache.clear();
    }
}

public void addApplicationListenerBean(String listenerBeanName) {
    synchronized(this.retrievalMutex) {
        this.defaultRetriever.applicationListenerBeans.add(listenerBeanName);
        this.retrieverCache.clear();
    }
}
...

    來看retrieveApplicationListeners方法的實現,這個很重要,因為發送Event之前,會先檢索出支持這種event的ApplicationListener。如下所示List-3:

  1. 遍歷applicationListeners,調用supportsEvent方法,如果支持,加將當前的ApplicationListener加入到結果集中。

  2. 之后遍歷applicationListenerBeans,先從BeanFactory中獲取對應的ApplicationListener實例,如果BeanFactory中含有對應的ApplicationListener,且supportsEvent方法返回true,那么將當前的ApplicationListener加入到結果集中。

  3. 最后調用AnnotationAwareOrderComparator進行排序。

    List-3

private Collection<ApplicationListener<?>> retrieveApplicationListeners(ResolvableType eventType, @Nullable Class<?> sourceType, @Nullable AbstractApplicationEventMulticaster.ListenerRetriever retriever) {
    List<ApplicationListener<?>> allListeners = new ArrayList();
    LinkedHashSet listeners;
    LinkedHashSet listenerBeans;
    synchronized(this.retrievalMutex) {
        listeners = new LinkedHashSet(this.defaultRetriever.applicationListeners);
        listenerBeans = new LinkedHashSet(this.defaultRetriever.applicationListenerBeans);
    }
    Iterator var7 = listeners.iterator();
    while(var7.hasNext()) {
        ApplicationListener<?> listener = (ApplicationListener)var7.next();
        if (this.supportsEvent(listener, eventType, sourceType)) {
            if (retriever != null) {
                retriever.applicationListeners.add(listener);
            }
            allListeners.add(listener);
        }
    }

    if (!listenerBeans.isEmpty()) {
        BeanFactory beanFactory = this.getBeanFactory();
        Iterator var15 = listenerBeans.iterator();
        while(var15.hasNext()) {
            String listenerBeanName = (String)var15.next();
            try {
                Class<?> listenerType = beanFactory.getType(listenerBeanName);
                if (listenerType == null || this.supportsEvent(listenerType, eventType)) {
                    ApplicationListener<?> listener = (ApplicationListener)beanFactory.getBean(listenerBeanName, ApplicationListener.class);
                    if (!allListeners.contains(listener) && this.supportsEvent(listener, eventType, sourceType)) {
                        if (retriever != null) {
                            retriever.applicationListenerBeans.add(listenerBeanName);
                        }
                        allListeners.add(listener);
                    }
                }
            } catch (NoSuchBeanDefinitionException var13) {
            }
        }
    }

    AnnotationAwareOrderComparator.sort(allListeners);
    return allListeners;
}

    AbstractApplicationEventMulticaster的子類,需要實現multicastEvent方法,我們來看下SimpleApplicationEventMulticaster是如何實現的。

    如下List-4所示,默認情況下taskExecutor是null。

    multicastEvent方法中調用父類的getApplicationListeners方法獲取支持Event的ApplicationListener,之后遍歷ApplicationListener,如果taskExecutor不是null,則交給Executor;否則逐個調用ApplicationListener的onApplicationEvent方法。

    List-4

public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
    @Nullable
    private Executor taskExecutor;

    public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {
        ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event);
        Iterator var4 = this.getApplicationListeners(event, type).iterator();
        while(var4.hasNext()) {
            ApplicationListener<?> listener = (ApplicationListener)var4.next();
            Executor executor = this.getTaskExecutor();
            if (executor != null) {
                executor.execute(() -> {
                    this.invokeListener(listener, event);
                });
            } else {
                this.invokeListener(listener, event);
            }
        }
    }

    private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
        try {
            listener.onApplicationEvent(event);
        } catch (ClassCastException var6) {
            String msg = var6.getMessage();
            if (msg != null && !this.matchesClassCastMessage(msg, event.getClass())) {
                throw var6;
            }
        }
    }
...

    Springboot中SpringApplicationRunListener的默認實現有個EventPublishingRunListener,如下List-5所示

    List-5

public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
	private final SimpleApplicationEventMulticaster initialMulticaster;
    ...
	@Override
	public void starting() {
		this.initialMulticaster.multicastEvent(
				new ApplicationStartingEvent(this.application, this.args));
	}

	@Override
	public void environmentPrepared(ConfigurableEnvironment environment) {
		this.initialMulticaster.multicastEvent(new ApplicationEnvironmentPreparedEvent(
				this.application, this.args, environment));
	}
    ...
	@Override
	public void started(ConfigurableApplicationContext context) {
		context.publishEvent(
				new ApplicationStartedEvent(this.application, this.args, context));
	}
    ...

    如List-5中所示,Springboot啟動的不同階段,會傳不同的event實現給EventPublishingRunListener,而EventPublishingRunListener則用Delete委托模式,交給initialMulticaster去處理。當然,started、running、failed事件則交給ConfigurableApplicationContext去處理。

    來看EventPublishingRunListener的構造方法如下List-6所示,從SpringApplication中獲取Listener,之后加入到SimpleApplicationEventMulticaster中,所以Springboot中的事件是先交給SpringApplicationRunListener,之后SpringApplicationRunListener再委托給ApplicationListener的實現類完成具體的。

    List-6

public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
	private final SpringApplication application;
	private final SimpleApplicationEventMulticaster initialMulticaster;
    ...
	public EventPublishingRunListener(SpringApplication application, String[] args) {
		this.application = application;
		this.args = args;
		this.initialMulticaster = new SimpleApplicationEventMulticaster();
		for (ApplicationListener<?> listener : application.getListeners()) {
			this.initialMulticaster.addApplicationListener(listener);
		}
	}
	...

    ApplicationListener的實現類如下圖2

          Springboot中AbstractApplicationEventMulticaster有什么作用

                                                                                     圖2

“Springboot中AbstractApplicationEventMulticaster有什么作用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

唐海县| 盐津县| 酒泉市| 兴仁县| 西乌珠穆沁旗| 安福县| 嘉黎县| 读书| 合阳县| 衡阳市| 南平市| 武乡县| 惠东县| 平塘县| 集安市| 西充县| 正定县| 武汉市| 南江县| 迁西县| 阿拉善右旗| 高清| 绥芬河市| 改则县| 革吉县| 青冈县| 襄垣县| 铁力市| 鄂托克前旗| 淄博市| 资阳市| 福安市| 兰西县| 同德县| 紫金县| 阳朔县| 正定县| 来凤县| 新沂市| 鲁甸县| 界首市|