springboot启动过程分析简书,springboot启动过程简单描述

  springboot启动过程分析简书,springboot启动过程简单描述

  

目录

1、创建SpringApplication1.1,判断网类型1.2、加载上下文初始化器1.3、加载监听器1.4、获得引导类类型2、执行弹簧应用的奔跑方法启动跳靴2.1、准备环境创建环境配置环境2.2,打印Banner2.3,创建弹簧上下文2.4、准备上下文应用环境的后置处理2.4.2、应用初始化器2.4.3、获取来源2.4.4,加载2.5、刷新上下文2.6、上下文刷新后2.7、执行回调跳羚启动类

 

  @ spring boot application公共类测试应用{ public static void main(String[]args){ spring application。运行(测试应用程序。class,args);} }弹簧靴应用程序注解

  @Target(ElementType .TYPE)@ Retention(保留策略.运行时)@ documentated @ Inherited @ spring boot configuration @ enable auto configuration @ components can(exclude filters={ @ Filter(type=Filter type .CUSTOM,classes=typeexcludefilter。class),@Filter(type=FilterType .CUSTOM,classes=autoconfigurationexcludefilter。class)})public @ interface spring boot应用程序{ @ spring boot应用程序注解上标注了@EnableAutoConfiguration,表示测试应用是引导类。

  跳羚的启动方法中传入了两个参数,引导类,和程序参数。

  公共静态可配置应用程序上下文运行(类。原始源,字符串.args) {返回运行(新类?[] { primarySource },args);}调用奔跑方法

  公共静态可配置应用程序上下文运行(类. primarySources,String[] args) {返回新的spring应用程序(主要来源).run(args);}运行方法中有两步,创建弹簧应用和执行弹簧应用的奔跑方法。

  

1、创建SpringApplication

春季应用的构造器

 

  公共spring应用程序(类。primarySources) { this(空,主要来源);}私有资源加载器私有SetClass?主要来源;公共spring应用(资源加载器资源加载器,类?主要来源){ //将资源加载器赋值成员变量,此处是取消这个。资源加载器=资源加载器;Assert.notNull(primarySources, primarySources不得为null’);//将引导类赋值成员变量这个。主源=新链接的哈希集(数组。as列表(主要来源));//判断网类型,赋值成员变量这个。webapplicationtype=webapplicationtype。扣除

  FromClasspath(); //加载初始化器 setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class)); //加载监听器 setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); //获得引导类 this.mainApplicationClass = deduceMainApplicationClass();}

 

  

1.1、判断web类型

//org.springframework.boot.WebApplicationType#deduceFromClasspathstatic WebApplicationType deduceFromClasspath() { //WEBFLUX_INDICATOR_CLASS = "org.springframework.web.reactive.DispatcherHandler";//JERSEY_INDICATOR_CLASS = "org.glassfish.jersey.servlet.ServletContainer"; if (ClassUtils.isPresent(WEBFLUX_INDICATOR_CLASS, null) && !ClassUtils.isPresent(WEBMVC_INDICATOR_CLASS, null) && !ClassUtils.isPresent(JERSEY_INDICATOR_CLASS, null)) { return WebApplicationType.REACTIVE; } //SERVLET_INDICATOR_CLASSES = { "javax.servlet.Servlet","org.springframework.web.context.ConfigurableWebApplicationContext" } for (String className : SERVLET_INDICATOR_CLASSES) { if (!ClassUtils.isPresent(className, null)) { return WebApplicationType.NONE; } } return WebApplicationType.SERVLET;}

 

  

1.2、加载上下文初始化器

利用spi加载 ApplicationContextInitializer 的实现类

 

  

private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) { return getSpringFactoriesInstances(type, new Class<?>[] {});}
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) { //获取classloader ClassLoader classLoader = getClassLoader(); // Use names and ensure unique to protect against duplicates //获取配置文件中接口实现类的全限定名 Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader)); //初始化 List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names); AnnotationAwareOrderComparator.sort(instances); //返回 return instances;}
public ClassLoader getClassLoader() { if (this.resourceLoader != null) { return this.resourceLoader.getClassLoader(); } return ClassUtils.getDefaultClassLoader();}
private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args, Set<String> names) { List<T> instances = new ArrayList<>(names.size()); for (String name : names) { try { Class<?> instanceClass = ClassUtils.forName(name, classLoader); Assert.isAssignable(type, instanceClass); Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes); T instance = (T) BeanUtils.instantiateClass(constructor, args); instances.add(instance); } catch (Throwable ex) { throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex); } } return instances;}

将初始化好的上下文初始化器设置到成员变量

 

  

//private List<ApplicationContextInitializer<?>> initializers;public void setInitializers(Collection<? extends ApplicationContextInitializer<?>> initializers) { this.initializers = new ArrayList<>(initializers);}

 

  

1.3、加载监听器

将初始化好的监听器设置到成员变量

 

  

//private List<ApplicationListener<?>> listeners;public void setListeners(Collection<? extends ApplicationListener<?>> listeners) { this.listeners = new ArrayList<>(listeners);}

 

  

1.4、获得引导类类型

private Class<?> deduceMainApplicationClass() { try { StackTraceElement[] stackTrace = new RuntimeException().getStackTrace(); for (StackTraceElement stackTraceElement : stackTrace) { //获取main方法的类 if ("main".equals(stackTraceElement.getMethodName())) { return Class.forName(stackTraceElement.getClassName()); } } } catch (ClassNotFoundException ex) { // Swallow and continue } return null;}

 

  

2、执行SpringApplication的run方法启动Springboot

public ConfigurableApplicationContext run(String... args) { //启动停止监听器 StopWatch stopWatch = new StopWatch(); stopWatch.start(); //Spring上下文 ConfigurableApplicationContext context = null; //错误导出 Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>(); configureHeadlessProperty(); //运行时监听器 SpringApplicationRunListeners listeners = getRunListeners(args); //启动运行时监听器 listeners.starting(); try { //生成ApplicationArguments ApplicationArguments applicationArguments = new DefaultApplicationArguments(args); //准备environment ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments); configureIgnoreBeanInfo(environment); //打印banner Banner printedBanner = printBanner(environment); //创建Spring上下文 context = createApplicationContext(); exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[] { ConfigurableApplicationContext.class }, context); //准备上下文 prepareContext(context, environment, listeners, applicationArguments, printedBanner); //刷新上下文 refreshContext(context); //上下文刷新后 afterRefresh(context, applicationArguments); //停止 停止监听器 stopWatch.stop(); if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch); } //停止运行时监听器 listeners.started(context); //执行回调 callRunners(context, applicationArguments); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, listeners); throw new IllegalStateException(ex); } try { listeners.running(context); } catch (Throwable ex) { handleRunFailure(context, ex, exceptionReporters, null); throw new IllegalStateException(ex); } return context;}

 

  

2.1、准备environment

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments) { // Create and configure the environment //创建environment ConfigurableEnvironment environment = getOrCreateEnvironment(); //配置environment configureEnvironment(environment, applicationArguments.getSourceArgs()); ConfigurationPropertySources.attach(environment); listeners.environmentPrepared(environment); bindToSpringApplication(environment); if (!this.isCustomEnvironment) { environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment, deduceEnvironmentClass()); } ConfigurationPropertySources.attach(environment); return environment;}

 

  

2.1.1、创建environment

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

这里根据web类型创建不同的environment

 

  

 

  

2.1.2、配置environment

protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) { if (this.addConversionService) { //转换服务 ConversionService conversionService = ApplicationConversionService.getSharedInstance(); environment.setConversionService((ConfigurableConversionService) conversionService); } configurePropertySources(environment, args); configureProfiles(environment, args);}

配置PropertySources

 

  

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 = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME; 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)); } }}

主要为了在PropertySources添加一个SimpleCommandLinePropertySource。

 

  配置profiles

  

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

将profile添加到environment

 

  

 

  

2.2、打印Banner

private Banner.Mode bannerMode = Banner.Mode.CONSOLE;private Banner printBanner(ConfigurableEnvironment environment) { //无需打印 if (this.bannerMode == Banner.Mode.OFF) { return null; } ResourceLoader resourceLoader = (this.resourceLoader != null) ? this.resourceLoader : new DefaultResourceLoader(getClassLoader()); SpringApplicationBannerPrinter bannerPrinter = new SpringApplicationBannerPrinter(resourceLoader, this.banner); if (this.bannerMode == Mode.LOG) { return bannerPrinter.print(environment, this.mainApplicationClass, logger); } return bannerPrinter.print(environment, this.mainApplicationClass, System.out);}

 

  

2.3、创建Spring上下文

//DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot."//+"web.servlet.context.AnnotationConfigServletWebServerApplicationContext";//DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework."//+"boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";//DEFAULT_CONTEXT_CLASS = "org.springframework.context."//+ "annotation.AnnotationConfigApplicationContext";protected ConfigurableApplicationContext createApplicationContext() { Class<?> contextClass = this.applicationContextClass; if (contextClass == null) { try { switch (this.webApplicationType) { case SERVLET: contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS); break; case REACTIVE: contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS); break; default: contextClass = Class.forName(DEFAULT_CONTEXT_CLASS); } } catch (ClassNotFoundException ex) { throw new IllegalStateException( "Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex); } } //初始化上下文并返回 return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);}

 

  

2.4、准备上下文

private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) { context.setEnvironment(environment); //ApplicationContext的后置处理 postProcessApplicationContext(context); //应用初始化器 applyInitializers(context); //运行时监听器的准备上下文监听 listeners.contextPrepared(context); if (this.logStartupInfo) { logStartupInfo(context.getParent() == null); logStartupProfileInfo(context); } // Add boot specific singleton beans //获取beanFactory ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); //将程序入参注册bean springApplicationArguments beanFactory.registerSingleton("springApplicationArguments", applicationArguments); //将banner注册bean springBootBanner if (printedBanner != null) { beanFactory.registerSingleton("springBootBanner", printedBanner); } //设置BeanDefinition是否允许重写 if (beanFactory instanceof DefaultListableBeanFactory) { ((DefaultListableBeanFactory) beanFactory) .setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } //初始化允许懒加载,设置BeanfactorypostProcessor if (this.lazyInitialization) { context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor()); } // Load the sources //获取source Set<Object> sources = getAllSources(); Assert.notEmpty(sources, "Sources must not be empty"); load(context, sources.toArray(new Object[0])); //运行时监听器,上下文加载完成 listeners.contextLoaded(context);}

 

  

2.4.1、ApplicationContext的后置处理

protected void postProcessApplicationContext(ConfigurableApplicationContext context) { //注册 beanNameGenerator if (this.beanNameGenerator != null) { context.getBeanFactory().registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, this.beanNameGenerator); } //注册 resourceLoader if (this.resourceLoader != null) { if (context instanceof GenericApplicationContext) { ((GenericApplicationContext) context).setResourceLoader(this.resourceLoader); } if (context instanceof DefaultResourceLoader) { ((DefaultResourceLoader) context).setClassLoader(this.resourceLoader.getClassLoader()); } } //设置 ConversionService if (this.addConversionService) { context.getBeanFactory().setConversionService(ApplicationConversionService.getSharedInstance()); }}
//org.springframework.boot.convert.ApplicationConversionService#getSharedInstancepublic static ConversionService getSharedInstance() { ApplicationConversionService sharedInstance = ApplicationConversionService.sharedInstance; if (sharedInstance == null) { synchronized (ApplicationConversionService.class) { sharedInstance = ApplicationConversionService.sharedInstance; if (sharedInstance == null) { sharedInstance = new ApplicationConversionService(); ApplicationConversionService.sharedInstance = sharedInstance; } } } return sharedInstance;}

 

  

2.4.2、应用初始化器

protected void applyInitializers(ConfigurableApplicationContext context) { for (ApplicationContextInitializer initializer : getInitializers()) { Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(), ApplicationContextInitializer.class); Assert.isInstanceOf(requiredType, context, "Unable to call initializer."); initializer.initialize(context); }}

执行所有实现了 ApplicationContextInitializer 接口的类的initialize方法。

 

  

 

  

2.4.3、获取sources

public Set<Object> getAllSources() { Set<Object> allSources = new LinkedHashSet<>(); if (!CollectionUtils.isEmpty(this.primarySources)) { allSources.addAll(this.primarySources); } if (!CollectionUtils.isEmpty(this.sources)) { allSources.addAll(this.sources); } return Collections.unmodifiableSet(allSources);}

这里组装了引导类和自定义的source

 

  

 

  

2.4.4、加载

protected void load(ApplicationContext context, Object[] sources) { if (logger.isDebugEnabled()) { logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources)); } //创建BeanDefinitionLoader 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); } //加载,spring的逻辑,这里会将引导类注册 loader.load();}
protected BeanDefinitionLoader createBeanDefinitionLoader(BeanDefinitionRegistry registry, Object[] sources) { return new BeanDefinitionLoader(registry, sources);}

 

  

2.5、刷新上下文

private void refreshContext(ConfigurableApplicationContext context) { refresh(context); if (this.registerShutdownHook) { try { //注册钩子关闭SpringBoot容器 context.registerShutdownHook(); } catch (AccessControlException ex) { // Not allowed in some environments. } }}

刷新

 

  

protected void refresh(ApplicationContext applicationContext) { Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext); //执行spring容器的刷新 ((AbstractApplicationContext) applicationContext).refresh();}

 

  

2.6、上下文刷新后

protected void afterRefresh(ConfigurableApplicationContext context, ApplicationArguments args) {}

这里是一个空实现,应该是作为模板扩展吧。

 

  

 

  

2.7、执行回调

private void callRunners(ApplicationContext context, ApplicationArguments args) { List<Object> runners = new ArrayList<>(); runners.addAll(context.getBeansOfType(ApplicationRunner.class).values()); runners.addAll(context.getBeansOfType(CommandLineRunner.class).values()); AnnotationAwareOrderComparator.sort(runners); for (Object runner : new LinkedHashSet<>(runners)) { if (runner instanceof ApplicationRunner) { callRunner((ApplicationRunner) runner, args); } if (runner instanceof CommandLineRunner) { callRunner((CommandLineRunner) runner, args); } }}

这里会调用所有实现了ApplicationRunner,CommandLineRunner的接口的实现类的run方法。

 

  到此这篇关于SpringBoot超详细分析启动流程的文章就介绍到这了,更多相关SpringBoot启动分析内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: