Maison  >  Article  >  Java  >  Analyse détaillée du code source du mécanisme d'événement Spring

Analyse détaillée du code source du mécanisme d'événement Spring

不言
不言avant
2019-03-27 10:35:162808parcourir

Ce que cet article vous apporte, c'est une analyse détaillée du code source du mécanisme d'événement Spring.Il a une certaine valeur de référence.Les amis dans le besoin peuvent s'y référer.J'espère qu'il vous sera utile.

Préface : Parce qu'il y a eu des problèmes lors de l'utilisation du mécanisme d'événements Spring auparavant, je suis allé comprendre le code source de cet article. Le mécanisme d'événement Spring est en fait une publication/abonnement d'événements (notez que l'abonnement au Spring fait référence à l'écoute).

PS : la version Spring est 5.1.5.RELEASE

Analyse du code source

Initialisation

La clé de l'initialisation est l'enregistrement des composants principaux

1. Initialisation et enregistrement de ApplicationEventPublisher. La méthode clé est la méthode prepareBeanFactory()

de AbstractApplicationContext 2. Initialisation et enregistrement de ApplicationEventMulticaster. 🎜>

3. La méthode clé pour l'initialisation et l'enregistrement d'ApplicationListener est la méthode registerListeners() de AbstractApplicationContext

Je n'entrerai pas dans les détails ici. Ceux qui sont intéressés peuvent suivre les méthodes clés en. eux-mêmes

Publication/abonnement d'événements

La méthode clé pour la publication/abonnement d'événements est submitEvent de AbstractApplicationContext. Le code source est le suivant :

<.>Grâce au suivi du code, il a été constaté que Spring utilise l'implémentation par défaut d'ApplicationEventMulticaster, SimpleApplicationEventMulticaster, pour déclencher la surveillance des événements. La méthode clé est la méthode multicastEvent(), et le code source est le suivant :
    protected void publishEvent(Object event, ResolvableType eventType) {
        // 避免空指针
        Assert.notNull(event, "Event must not be null");
        if (logger.isTraceEnabled()) {
            logger.trace("Publishing event in " + getDisplayName() + ": " + event);
        }

        // 处理event对象,将其转换为ApplicationEvent
        ApplicationEvent applicationEvent;
        if (event instanceof ApplicationEvent) {
            applicationEvent = (ApplicationEvent) event;
        }
        else {
            applicationEvent = new PayloadApplicationEvent<Object>(this, event);
            if (eventType == null) {
                eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType();
            }
        }

        // 是否延迟多播,即将事件发布到所有监听器中
        if (this.earlyApplicationEvents != null) {
            this.earlyApplicationEvents.add(applicationEvent);
        }
        else {
            //此处为事件监听处理器的调用关键
            getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
        }

        // 是否将事件发布到父容器中
        if (this.parent != null) {
            if (this.parent instanceof AbstractApplicationContext) {
                ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
            }
            else {
                this.parent.publishEvent(event);
            }
        }
    }

<.>Cet article est terminé ici. Pour d'autres contenus passionnants, vous pouvez prêter attention au

Tutoriel vidéo Java sur le site Web PHP chinois
    @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) {//线程池不为null,则异步调用监听器
                executor.execute(new Runnable() {
                    @Override
                    public void run() {
                        invokeListener(listener, event);
                    }
                });
            }
            else {// 同步调用监听器
                invokeListener(listener, event);
            }
        }
    }
Colonne !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer