• 源码阅读简记~springboot启动事件


    事件发布

        public void environmentPrepared(ConfigurableEnvironment environment) {
            for (SpringApplicationRunListener listener : this.listeners) {
                listener.environmentPrepared(environment);
            }
        }
        private void publishEvent(SpringApplicationEvent event) {
            this.multicaster.multicastEvent(event);
        }

    spring事件

        @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);
                }
            }
        }

    通知listener

        @SuppressWarnings({"unchecked", "rawtypes"})
        protected void invokeListener(ApplicationListener listener, ApplicationEvent event) {
            ErrorHandler errorHandler = getErrorHandler();
            if (errorHandler != null) {
                try {
                    listener.onApplicationEvent(event);
                }
                catch (Throwable err) {
                    errorHandler.handleError(err);
                }
            }
            else {
                try {
                    listener.onApplicationEvent(event);
                }
                catch (ClassCastException ex) {
                    // Possibly a lambda-defined listener which we could not resolve the generic event type for
                    LogFactory.getLog(getClass()).debug("Non-matching event type for listener: " + listener, ex);
                }
            }
        }

    大范围的观察者模式,初始是通过META-INF/spring.factories加载来的,还有通过容器注册的,还有refresh的时候注册进来的

    # PropertySource Loaders
    org.springframework.boot.env.PropertySourceLoader=
    org.springframework.boot.env.PropertiesPropertySourceLoader,
    org.springframework.boot.env.YamlPropertySourceLoader
    
    # Run Listeners
    org.springframework.boot.SpringApplicationRunListener=
    org.springframework.boot.context.event.EventPublishingRunListener
    
    # Application Context Initializers
    org.springframework.context.ApplicationContextInitializer=
    org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,
    org.springframework.boot.context.ContextIdApplicationContextInitializer,
    org.springframework.boot.context.config.DelegatingApplicationContextInitializer,
    org.springframework.boot.context.web.ServerPortInfoApplicationContextInitializer
    
    # Application Listeners
    org.springframework.context.ApplicationListener=
    org.springframework.boot.builder.ParentContextCloserApplicationListener,
    org.springframework.boot.context.FileEncodingApplicationListener,
    org.springframework.boot.context.config.AnsiOutputApplicationListener,
    org.springframework.boot.context.config.ConfigFileApplicationListener,
    org.springframework.boot.context.config.DelegatingApplicationListener,
    org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener,
    org.springframework.boot.logging.ClasspathLoggingApplicationListener,
    org.springframework.boot.logging.LoggingApplicationListener
    
    # Environment Post Processors
    org.springframework.boot.env.EnvironmentPostProcessor=
    org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,
    org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor

    通过后处理器添加

    @Override
            public Object postProcessAfterInitialization(Object bean, String beanName) {
                if (this.applicationContext != null && bean instanceof ApplicationListener) {
                    // potentially not detected as a listener by getBeanNamesForType retrieval
                    Boolean flag = this.singletonNames.get(beanName);
                    if (Boolean.TRUE.equals(flag)) {
                        // singleton bean (top-level or inner): register on the fly
                        this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
                    }
                    else if (flag == null) {
                        if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
                            // inner bean with other scope - can't reliably process events
                            logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
                                    "but is not reachable for event multicasting by its containing ApplicationContext " +
                                    "because it does not have singleton scope. Only top-level listener beans are allowed " +
                                    "to be of non-singleton scope.");
                        }
                        this.singletonNames.put(beanName, Boolean.FALSE);
                    }
                }
                return bean;
            }
  • 相关阅读:
    C# winform 获取鼠标点击位置
    C# 读取带有命名空间的xml
    ImageUtility辅助类
    C# 读取XML
    C# 根据生日获取年龄
    C# 将 WebService 封装成动态库
    C# 生成条形码
    C# Ftp Client 基本操作
    C# SQL帮助类
    C# 解压缩文件
  • 原文地址:https://www.cnblogs.com/it-worker365/p/14737996.html
Copyright © 2020-2023  润新知