SpringBoot 启动流程 (3)

根据不同的应用类型初始化不同的山下文应用类

protected ConfigurableApplicationContext createApplicationContext() { return this.applicationContextFactory.create(this.webApplicationType); } 准备应用上下文 private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) { // 设置应用上下文的 environment context.setEnvironment(environment); // 应用山下文的后置处理 postProcessApplicationContext(context); // 为上下文应用所有初始化器,执行前面设置的 ApplicationContextInitializer 类 applyInitializers(context); // 触发所有 SpringApplicationRunListener 监听器的 contextPrepared 事件方法。添加所有的事件监听器 listeners.contextPrepared(context); bootstrapContext.close(context); // 记录启动日志 if (this.logStartupInfo) { logStartupInfo(context.getParent() == null); logStartupProfileInfo(context); } // Add boot specific singleton beans // 注册启动参数bean,将容器指定的参数封装成bean,注入容器 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()); } // Load the sources // 加载所有资源 Set<Object> sources = getAllSources(); Assert.notEmpty(sources, "Sources must not be empty"); // 将 bean 加载到上下文中 load(context, sources.toArray(new Object[0])); // 触发所有 SpringApplicationRunListener 监听器的 contextLoaded 事件方法 listeners.contextLoaded(context); } protected void load(ApplicationContext context, Object[] sources) { if (logger.isDebugEnabled()) { logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources)); } BeanDefinitionLoader loader = createBeanDefinitionLoader(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(); } // 后续会使用其将主资源加载到上下文中去,供后续解析使用 BeanDefinitionLoader(BeanDefinitionRegistry registry, Object... sources) { Assert.notNull(registry, "Registry must not be null"); Assert.notEmpty(sources, "Sources must not be empty"); this.sources = sources; this.annotatedReader = new AnnotatedBeanDefinitionReader(registry); this.xmlReader = (XML_ENABLED ? new XmlBeanDefinitionReader(registry) : null); this.groovyReader = (isGroovyPresent() ? new GroovyBeanDefinitionReader(registry) : null); this.scanner = new ClassPathBeanDefinitionScanner(registry); this.scanner.addExcludeFilter(new ClassExcludeFilter(sources)); } void load() { for (Object source : this.sources) { load(source); } } private void load(Object source) { Assert.notNull(source, "Source must not be null"); if (source instanceof Class<?>) { // Class 的方式加载 load((Class<?>) source); return; } if (source instanceof Resource) { // Resource 资源的方式加载 load((Resource) source); return; } if (source instanceof Package) { load((Package) source); return; } if (source instanceof CharSequence) { load((CharSequence) source); return; } throw new IllegalArgumentException("Invalid source type " + source.getClass()); } private void load(Class<?> source) { if (isGroovyPresent() && GroovyBeanDefinitionSource.class.isAssignableFrom(source)) { // Any GroovyLoaders added in beans{} DSL can contribute beans here GroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class); ((GroovyBeanDefinitionReader) this.groovyReader).beans(loader.getBeans()); } if (isEligible(source)) { // 将符合条件的类注册到应用上下文 this.annotatedReader.register(source); } } // 不是常规的闭包并且不是匿名类,即可 private boolean isEligible(Class<?> type) { return !(type.isAnonymousClass() || isGroovyClosure(type) || hasNoConstructors(type)); } 刷新应用上下文

最终会调用到 AbstractApplicationContext 抽象类中的 refresh() 方法中去

refreshContext(context); 刷新后应用上下文调用

空方法,用于扩展

执行所有的 Runner 运行器

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpydfx.html