springboot源码1---springboot启动流程

应用初始化

    public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
         this.sources = new LinkedHashSet();
         this.bannerMode = Mode.CONSOLE;
         this.logStartupInfo = true;
         this.addCommandLineProperties = true;
         this.addConversionService = true;
         this.headless = true;
         this.registerShutdownHook = true;
         this.additionalProfiles = new HashSet();
         this.isCustomEnvironment = false;
         this.lazyInitialization = false;
         this.resourceLoader = resourceLoader;
         Assert.notNull(primarySources, "PrimarySources must not be null");
         this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
         this.webApplicationType = WebApplicationType.deduceFromClasspath();
         this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
         this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
         this.mainApplicationClass = this.deduceMainApplicationClass();
     }

推断web应用类型

    static WebApplicationType deduceFromClasspath() {
        if (ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler", (ClassLoader)null) && !ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", (ClassLoader)null) && !ClassUtils.isPresent("org.glassfish.jersey.servlet.ServletContainer", (ClassLoader)null)) {
            return REACTIVE;
        } else {
            String[] var0 = SERVLET_INDICATOR_CLASSES;
            int var1 = var0.length;

            for(int var2 = 0; var2 < var1; ++var2) {
                String className = var0[var2];
                if (!ClassUtils.isPresent(className, (ClassLoader)null)) {
                    return NONE;
                }
            }

            return SERVLET;
        }
    }

加载ApplicationContextInitializer

从spring.factories文件加载ApplicationContextInitializer
在这里插入图片描述

加载ApplicationListener

从spring.factories文件加载ApplicationListener
在这里插入图片描述

推断主类

根据调用栈推断主类

    private Class<?> deduceMainApplicationClass() {
        try {
            StackTraceElement[] stackTrace = (new RuntimeException()).getStackTrace();
            StackTraceElement[] var2 = stackTrace;
            int var3 = stackTrace.length;

            for(int var4 = 0; var4 < var3; ++var4) {
                StackTraceElement stackTraceElement = var2[var4];
                if ("main".equals(stackTraceElement.getMethodName())) {
                    return Class.forName(stackTraceElement.getClassName());
                }
            }
        } catch (ClassNotFoundException var6) {
        }

        return null;
    }

应用启动

加载运行监听器

从spring.factories文件加载SpringApplicationRunListener,只获取到EventPublishingRunListener(用于事件监听),它持有1个广播器(间接持有ApplicationListener),广播器会根据事件类型筛选ApplicationListener

private SpringApplicationRunListeners getRunListeners(String[] args) {
      Class<?>[] types = new Class[]{SpringApplication.class, String[].class};
      return new SpringApplicationRunListeners(logger, this.getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
}

在这里插入图片描述

发布启动事件

有4个listener可以处理
在这里插入图片描述

构建日志系统(LoggingApplicationListener)

    private void onApplicationStartingEvent(ApplicationStartingEvent event) {
        this.loggingSystem = LoggingSystem.get(event.getSpringApplication().getClassLoader());
        this.loggingSystem.beforeInitialize();
    }
    
        public static LoggingSystem get(ClassLoader classLoader) {
        String loggingSystem = System.getProperty(SYSTEM_PROPERTY);
        if (StringUtils.hasLength(loggingSystem)) {
            return (LoggingSystem)("none".equals(loggingSystem) ? new LoggingSystem.NoOpLoggingSystem() : get(classLoader, loggingSystem));
        } else {
            return (LoggingSystem)SYSTEMS.entrySet().stream().filter((entry) -> {
                return ClassUtils.isPresent((String)entry.getKey(), classLoader);
            }).map((entry) -> {
                return get(classLoader, (String)entry.getValue());
            }).findFirst().orElseThrow(() -> {
                return new IllegalStateException("No suitable logging system located");
            });
        }
    }
    
    static {
        Map<String, String> systems = new LinkedHashMap();
        systems.put("ch.qos.logback.core.Appender", "org.springframework.boot.logging.logback.LogbackLoggingSystem");
        systems.put("org.apache.logging.log4j.core.impl.Log4jContextFactory", "org.springframework.boot.logging.log4j2.Log4J2LoggingSystem");
        systems.put("java.util.logging.LogManager", "org.springframework.boot.logging.java.JavaLoggingSystem");
        SYSTEMS = Collections.unmodifiableMap(systems);
    }

利用classloader依次加载logback、log4j2、jul日志系统,谁先加载成功就使用它,这也是为什么springboot底层默认使用的是logback。

后台预热关键组件(BackgroudPreinitializer)

public class BackgroundPreinitializer implements ApplicationListener<SpringApplicationEvent> {
    public static final String IGNORE_BACKGROUNDPREINITIALIZER_PROPERTY_NAME = "spring.backgroundpreinitializer.ignore";
    private static final AtomicBoolean preinitializationStarted = new AtomicBoolean(false);
    private static final CountDownLatch preinitializationComplete = new CountDownLatch(1);

    public BackgroundPreinitializer() {
    }

    public void onApplicationEvent(SpringApplicationEvent event) {
        if (!Boolean.getBoolean("spring.backgroundpreinitializer.ignore") && event instanceof ApplicationStartingEvent && this.multipleProcessors() && preinitializationStarted.compareAndSet(false, true)) {
            this.performPreinitialization();
        }

        if ((event instanceof ApplicationReadyEvent || event instanceof ApplicationFailedEvent) && preinitializationStarted.get()) {
            try {
                preinitializationComplete.await();
            } catch (InterruptedException var3) {
                Thread.currentThread().interrupt();
            }
        }

    }

    private void performPreinitialization() {
        try {
            Thread thread = new Thread(new Runnable() {
                public void run() {
                    this.runSafely(new BackgroundPreinitializer.ConversionServiceInitializer());
                    this.runSafely(new BackgroundPreinitializer.ValidationInitializer());
                    this.runSafely(new BackgroundPreinitializer.MessageConverterInitializer());
                    this.runSafely(new BackgroundPreinitializer.JacksonInitializer());
                    this.runSafely(new BackgroundPreinitializer.CharsetInitializer());
                    BackgroundPreinitializer.preinitializationComplete.countDown();
                }

                public void runSafely(Runnable runnable) {
                    try {
                        runnable.run();
                    } catch (Throwable var3) {
                    }

                }
            }, "background-preinit");
            thread.start();
        } catch (Exception var2) {
            preinitializationComplete.countDown();
        }

    }

创建后台线程预热ConversionServiceInitializer、ValidationInitializer、MessageConverterInitializer、JacksonInitializer、CharsetInitializer组件,因为这些组件挺耗时。

准备environment

    ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
    ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
    
    private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) {
        ConfigurableEnvironment environment = this.getOrCreateEnvironment();
        this.configureEnvironment((ConfigurableEnvironment)environment, applicationArguments.getSourceArgs());
        //把ConfigurationPropertySourcesPropertySource作为第1个PropertySource
        ConfigurationPropertySources.attach((Environment)environment);
        listeners.environmentPrepared((ConfigurableEnvironment)environment);
        this.bindToSpringApplication((ConfigurableEnvironment)environment);
        if (!this.isCustomEnvironment) {
            environment = (new EnvironmentConverter(this.getClassLoader())).convertEnvironmentIfNecessary((ConfigurableEnvironment)environment, this.deduceEnvironmentClass());
        }
		//删除ConfigurationPropertySourcesPropertySource
        ConfigurationPropertySources.attach((Environment)environment);
        return (ConfigurableEnvironment)environment;
    }

    private ConfigurableEnvironment getOrCreateEnvironment() {
        if (this.environment != null) {
            return this.environment;
        } else {
            switch(this.webApplicationType) {
            case SERVLET:
                return new StandardServletEnvironment();
            case REACTIVE:
                return new StandardReactiveWebEnvironment();
            default:
                return new StandardEnvironment();
            }
        }
    }

    protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
        if (this.addConversionService) {
            ConversionService conversionService = ApplicationConversionService.getSharedInstance();
            environment.setConversionService((ConfigurableConversionService)conversionService);
        }

        this.configurePropertySources(environment, args);
        this.configureProfiles(environment, args);
    }

    protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) {
        MutablePropertySources sources = environment.getPropertySources();
        if (this.defaultProperties != null && !this.defaultProperties.isEmpty()) {
            sources.addLast(new MapPropertySource("defaultProperties", this.defaultProperties));
        }

        if (this.addCommandLineProperties && args.length > 0) {
            String name = "commandLineArgs";
            if (sources.contains(name)) {
                PropertySource<?> source = sources.get(name);
                CompositePropertySource composite = new CompositePropertySource(name);
                composite.addPropertySource(new SimpleCommandLinePropertySource("springApplicationCommandLineArgs", args));
                composite.addPropertySource(source);
                sources.replace(name, composite);
            } else {
                sources.addFirst(new SimpleCommandLinePropertySource(args));
            }
        }

    }

    protected void configureProfiles(ConfigurableEnvironment environment, String[] args) {
        Set<String> profiles = new LinkedHashSet(this.additionalProfiles);
        profiles.addAll(Arrays.asList(environment.getActiveProfiles()));
        environment.setActiveProfiles(StringUtils.toStringArray(profiles));
    }

environment最终持有的PropertySource
environment中的PropertySource
总结

1.把命令行参数封装成ApplicationArguments 
2.创建StandardServletEnvironment,这个过程中先后添加了servlet环境变量、java系统属性(比如-Dspring.profiles.active)、操作系统环境变量
3.给environment设置ApplicationConversionService
4.把命令行参数解析成k,v后封装成SimpleCommandLinePropertySource,添加到environment最前面,方便后续优先获取
5.设置environment的activeProfiles,解析参数--spring.profiles.active
6.把ConfigurationPropertySourcesPropertySource添加到environment最前面
7.发布environment准备好事件

发布environment准备好事件

支持环境就绪事件的listener
在这里插入图片描述

解析配置文件(ConfigFileApplicationListener)

    private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {
        //从spring.factories文件加载EnvironmentPostProcessor
        List<EnvironmentPostProcessor> postProcessors = this.loadPostProcessors();
        //把自己也添加进去
        postProcessors.add(this);
        AnnotationAwareOrderComparator.sort(postProcessors);
        Iterator var3 = postProcessors.iterator();

        while(var3.hasNext()) {
            EnvironmentPostProcessor postProcessor = (EnvironmentPostProcessor)var3.next();
            postProcessor.postProcessEnvironment(event.getEnvironment(), event.getSpringApplication());
        }

    }

排序后的EnvironmentPostProcessor
在这里插入图片描述
总结

1.从spring.factories文件加载EnvironmentPostProcessor到postProcessors中
2.把自身也添加进postProcessors,因为它也实现了EnvironmentPostProcessor
3.对processors进行排序,遍历调用postProcessEnvironment方法

初始化日志系统(LoggingApplicationListener)

public class LoggingApplicationListener implements GenericApplicationListener {
    private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {
        if (this.loggingSystem == null) {
            this.loggingSystem = LoggingSystem.get(event.getSpringApplication().getClassLoader());
        }

        this.initialize(event.getEnvironment(), event.getSpringApplication().getClassLoader());
    }

  protected void initialize(ConfigurableEnvironment environment, ClassLoader classLoader) {
  		//把一些默认的日志属性设置成java系统属性
        (new LoggingSystemProperties(environment)).apply();
        this.logFile = LogFile.get(environment);
        if (this.logFile != null) {
            this.logFile.applyToSystemProperties();
        }

        this.loggerGroups = new LoggerGroups(DEFAULT_GROUP_LOGGERS);
        //根据debug、trace属性来设置日志级别LogLevel.DEBUG、LogLevel.TRACE
        this.initializeEarlyLoggingLevel(environment);
        //根据logging.config属性获取到日志的配置文件路径,初始化日志系统
        this.initializeSystem(environment, this.loggingSystem, this.logFile);
        //初始化最终的日志级别
        this.initializeFinalLoggingLevels(environment, this.loggingSystem);
        this.registerShutdownHookIfNecessary(environment, this.loggingSystem);
    }

    private void initializeEarlyLoggingLevel(ConfigurableEnvironment environment) {
        if (this.parseArgs && this.springBootLogging == null) {
            if (this.isSet(environment, "debug")) {
                this.springBootLogging = LogLevel.DEBUG;
            }

            if (this.isSet(environment, "trace")) {
                this.springBootLogging = LogLevel.TRACE;
            }
        }

    }
    
    private void initializeSystem(ConfigurableEnvironment environment, LoggingSystem system, LogFile logFile) {
        LoggingInitializationContext initializationContext = new LoggingInitializationContext(environment);
        String logConfig = environment.getProperty("logging.config");
        if (this.ignoreLogConfig(logConfig)) {
            system.initialize(initializationContext, (String)null, logFile);
        } else {
            try {
                ResourceUtils.getURL(logConfig).openStream().close();
                system.initialize(initializationContext, logConfig, logFile);
            } catch (Exception var7) {
                System.err.println("Logging system failed to initialize using configuration from '" + logConfig + "'");
                var7.printStackTrace(System.err);
                throw new IllegalStateException(var7);
            }
        }

    }

    private void initializeFinalLoggingLevels(ConfigurableEnvironment environment, LoggingSystem system) {
        this.bindLoggerGroups(environment);
        if (this.springBootLogging != null) {
            this.initializeLogLevel(system, this.springBootLogging);
        }

        this.setLogLevels(system, environment);
    }
}

public class LoggingSystemProperties {
    public static final String PID_KEY = "PID";
    public static final String EXCEPTION_CONVERSION_WORD = "LOG_EXCEPTION_CONVERSION_WORD";
    public static final String LOG_FILE = "LOG_FILE";
    public static final String LOG_PATH = "LOG_PATH";
    public static final String CONSOLE_LOG_PATTERN = "CONSOLE_LOG_PATTERN";
    public static final String FILE_CLEAN_HISTORY_ON_START = "LOG_FILE_CLEAN_HISTORY_ON_START";
    public static final String FILE_LOG_PATTERN = "FILE_LOG_PATTERN";
    public static final String FILE_MAX_HISTORY = "LOG_FILE_MAX_HISTORY";
    public static final String FILE_MAX_SIZE = "LOG_FILE_MAX_SIZE";
    public static final String FILE_TOTAL_SIZE_CAP = "LOG_FILE_TOTAL_SIZE_CAP";
    public static final String LOG_LEVEL_PATTERN = "LOG_LEVEL_PATTERN";
    public static final String LOG_DATEFORMAT_PATTERN = "LOG_DATEFORMAT_PATTERN";
    public static final String ROLLING_FILE_NAME_PATTERN = "ROLLING_FILE_NAME_PATTERN";
    private final Environment environment;

    public LoggingSystemProperties(Environment environment) {
        Assert.notNull(environment, "Environment must not be null");
        this.environment = environment;
    }

    public void apply() {
        this.apply((LogFile)null);
    }

    public void apply(LogFile logFile) {
        //持有environment的PropertySources
        PropertyResolver resolver = this.getPropertyResolver();
        this.setSystemProperty(resolver, "LOG_EXCEPTION_CONVERSION_WORD", "exception-conversion-word");
        this.setSystemProperty("PID", (new ApplicationPid()).toString());
        this.setSystemProperty(resolver, "CONSOLE_LOG_PATTERN", "pattern.console");
        this.setSystemProperty(resolver, "FILE_LOG_PATTERN", "pattern.file");
        this.setSystemProperty(resolver, "LOG_FILE_CLEAN_HISTORY_ON_START", "file.clean-history-on-start");
        this.setSystemProperty(resolver, "LOG_FILE_MAX_HISTORY", "file.max-history");
        this.setSystemProperty(resolver, "LOG_FILE_MAX_SIZE", "file.max-size");
        this.setSystemProperty(resolver, "LOG_FILE_TOTAL_SIZE_CAP", "file.total-size-cap");
        this.setSystemProperty(resolver, "LOG_LEVEL_PATTERN", "pattern.level");
        this.setSystemProperty(resolver, "LOG_DATEFORMAT_PATTERN", "pattern.dateformat");
        this.setSystemProperty(resolver, "ROLLING_FILE_NAME_PATTERN", "pattern.rolling-file-name");
        if (logFile != null) {
            logFile.applyToSystemProperties();
        }

    }
}

总结:

1.把日志系统的一些默认属性设置成java系统属性
2.根据debug、trace属性来设置对应的日志级别
3.根据logging.config属性来获取到配置文件,并初始化日志系统
4.确定最终日志级别

事件转播(DelegatingApplicationListener)

public class DelegatingApplicationListener implements ApplicationListener<ApplicationEvent>, Ordered {
    private static final String PROPERTY_NAME = "context.listener.classes"
    private int order = 0;
    private SimpleApplicationEventMulticaster multicaster;

    public DelegatingApplicationListener() {
    }

    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ApplicationEnvironmentPreparedEvent) {
            List<ApplicationListener<ApplicationEvent>> delegates = this.getListeners(((ApplicationEnvironmentPreparedEvent)event).getEnvironment());
            if (delegates.isEmpty()) {
                return;
            }

            this.multicaster = new SimpleApplicationEventMulticaster();
            Iterator var3 = delegates.iterator();

            while(var3.hasNext()) {
                ApplicationListener<ApplicationEvent> listener = (ApplicationListener)var3.next();
                this.multicaster.addApplicationListener(listener);
            }
        }

        if (this.multicaster != null) {
            this.multicaster.multicastEvent(event);
        }

    }

    private List<ApplicationListener<ApplicationEvent>> getListeners(ConfigurableEnvironment environment) {
        if (environment == null) {
            return Collections.emptyList();
        } else {
            String classNames = environment.getProperty("context.listener.classes");
            List<ApplicationListener<ApplicationEvent>> listeners = new ArrayList();
            if (StringUtils.hasLength(classNames)) {
                Iterator var4 = StringUtils.commaDelimitedListToSet(classNames).iterator();

                while(var4.hasNext()) {
                    String className = (String)var4.next();

                    try {
                        Class<?> clazz = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader());
                        Assert.isAssignable(ApplicationListener.class, clazz, "class [" + className + "] must implement ApplicationListener");
                        listeners.add((ApplicationListener)BeanUtils.instantiateClass(clazz));
                    } catch (Exception var7) {
                        throw new ApplicationContextException("Failed to load context listener class [" + className + "]", var7);
                    }
                }
            }

            AnnotationAwareOrderComparator.sort(listeners);
            return listeners;
        }
    }
}

总结

1.在收到应用启动事件时会创建context.listener.classes指定的ApplicationListener,把这些listener加入广播器中。
2.后续收到的所有事件再转播给这些listener,起到了1个代理作用
3.扩展点,第2种添加ApplicationListener的方法,第1种是通过spring.factories文件配置

打印Banner

    Banner print(Environment environment, Class<?> sourceClass, PrintStream out) {
        Banner banner = this.getBanner(environment);
        banner.printBanner(environment, sourceClass, out);
        return new SpringApplicationBannerPrinter.PrintedBanner(banner, sourceClass);
    }

    private Banner getBanner(Environment environment) {
        SpringApplicationBannerPrinter.Banners banners = new SpringApplicationBannerPrinter.Banners();
        banners.addIfNotNull(this.getImageBanner(environment));
        banners.addIfNotNull(this.getTextBanner(environment));
        if (banners.hasAtLeastOneBanner()) {
            return banners;
        } else {
            return this.fallbackBanner != null ? this.fallbackBanner : DEFAULT_BANNER;
        }
    }
    
    private Banner getTextBanner(Environment environment) {
        //默认取类路径下的banner.txt
        String location = environment.getProperty("spring.banner.location", "banner.txt");
        Resource resource = this.resourceLoader.getResource(location);
        return resource.exists() ? new ResourceBanner(resource) : null;
    }

    private Banner getImageBanner(Environment environment) {
        String location = environment.getProperty("spring.banner.image.location");
        if (StringUtils.hasLength(location)) {
            Resource resource = this.resourceLoader.getResource(location);
            return resource.exists() ? new ImageBanner(resource) : null;
        } else {
            String[] var3 = IMAGE_EXTENSION;
            int var4 = var3.length;

            for(int var5 = 0; var5 < var4; ++var5) {
                String ext = var3[var5];
                Resource resource = this.resourceLoader.getResource("banner." + ext);
                if (resource.exists()) {
                    return new ImageBanner(resource);
                }
            }

            return null;
        }
    }

总结

1.文本banner扩展
    类路径下放1个banner.txt文件
    通过spring.banner.location属性指定路径
2.图案banner扩展
    类路径下放banner.gif、banner.jpg、banner.png文件
    通过spring.banner.image.location属性指定路径

准备context

    private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
        context.setEnvironment(environment);
        this.postProcessApplicationContext(context);
        this.applyInitializers(context);
        listeners.contextPrepared(context);
        if (this.logStartupInfo) {
            this.logStartupInfo(context.getParent() == null);
            this.logStartupProfileInfo(context);
        }

        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
        if (printedBanner != null) {
            beanFactory.registerSingleton("springBootBanner", printedBanner);
        }

        if (beanFactory instanceof DefaultListableBeanFactory) {
            ((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
        }

        if (this.lazyInitialization) {
            context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
        }

        Set<Object> sources = this.getAllSources();
        Assert.notEmpty(sources, "Sources must not be empty");
        this.load(context, sources.toArray(new Object[0]));
        listeners.contextLoaded(context);
    }


    protected void postProcessApplicationContext(ConfigurableApplicationContext context) {
        if (this.beanNameGenerator != null) {
            context.getBeanFactory().registerSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator", this.beanNameGenerator);
        }

        if (this.resourceLoader != null) {
            if (context instanceof GenericApplicationContext) {
                ((GenericApplicationContext)context).setResourceLoader(this.resourceLoader);
            }

            if (context instanceof DefaultResourceLoader) {
                ((DefaultResourceLoader)context).setClassLoader(this.resourceLoader.getClassLoader());
            }
        }

        if (this.addConversionService) {
            context.getBeanFactory().setConversionService(ApplicationConversionService.getSharedInstance());
        }

    }

    protected void applyInitializers(ConfigurableApplicationContext context) {
        Iterator var2 = this.getInitializers().iterator();

        while(var2.hasNext()) {
            ApplicationContextInitializer initializer = (ApplicationContextInitializer)var2.next();
            Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(), ApplicationContextInitializer.class);
            Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
            initializer.initialize(context);
        }

    }

总结

1.创建AnnotationConfigServletWebServerApplicationContext
2.使用从spring.factories文件获取的初始化器对context进行初始化
3.发布context初始化完成事件
4.把命令行参数注册到context
5.设置context的allowBeanDefinitionOverriding属性
6.把主类注册到context
7.发布应用准备好事件

context初始化

在这里插入图片描述
总结

这儿可以对context做一些扩展,比如添加后置处理器、注册bean等

发布context初始化完成事件

在这里插入图片描述
总结

1.BackgroundPreinitializer啥也没干
2.DelegatingApplicationListener同前面一样,只是起代理作用

注册主类

    protected void load(ApplicationContext context, Object[] sources) {
        if (logger.isDebugEnabled()) {
            logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
        }

        BeanDefinitionLoader loader = this.createBeanDefinitionLoader(this.getBeanDefinitionRegistry(context), sources);
        if (this.beanNameGenerator != null) {
            loader.setBeanNameGenerator(this.beanNameGenerator);
        }

        if (this.resourceLoader != null) {
            loader.setResourceLoader(this.resourceLoader);
        }

        if (this.environment != null) {
            loader.setEnvironment(this.environment);
        }

        loader.load();
    }

发布应用准备好事件

    public void contextLoaded(ConfigurableApplicationContext context) {
        ApplicationListener listener;
        for(Iterator var2 = this.application.getListeners().iterator(); var2.hasNext(); context.addApplicationListener(listener)) {
            listener = (ApplicationListener)var2.next();
            if (listener instanceof ApplicationContextAware) {
                ((ApplicationContextAware)listener).setApplicationContext(context);
            }
        }

        this.initialMulticaster.multicastEvent(new ApplicationPreparedEvent(this.application, this.args, context));
    }

有5个listener可以处理
在这里插入图片描述

总结

1.实现了ApplicationContextAware的listener会保存context
2.ConfigFileApplicationListener,添加了1个BeanFactoryPostProcessor=PropertySourceOrderingPostProcessor
4.LoggingApplicationListener,把日志系统作为单例注册到了ioc

刷新context

略,详见spring源码分析

发布context刷新完成事件

子类扩展实现。

发布应用启动完成事件

    public void started(ConfigurableApplicationContext context) {
        context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context));
    }

总结

和前面的发布事件不同,没有通过多播器发布事件,而是直接通过context发布的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值