zoukankan      html  css  js  c++  java
  • springboot 源码笔记

    1.springAppication构造器

      基于getSpringFactoriesInstances方法构造如下类(获取文件内容在META-INF/spring.factories文件中)

      1.1 初始化ApplicationContextInitializer.class

    # 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.web.context.ServerPortInfoApplicationContextInitializer

      1.2 初始化ApplicationListener.class

    # Application Listeners
    org.springframework.context.ApplicationListener=
    org.springframework.boot.ClearCachesApplicationListener,
    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.context.logging.ClasspathLoggingApplicationListener,
    org.springframework.boot.context.logging.LoggingApplicationListener,
    org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

    2.run方法

    		StopWatch stopWatch = new StopWatch();//构造时间观察器
    		stopWatch.start();// 打印一个开始时间
    		ConfigurableApplicationContext context = null;
    		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
    		configureHeadlessProperty();// 配置headless 依据java.awt.headless
    		SpringApplicationRunListeners listeners = getRunListeners(args);// 解析如下
    		// getSpringFactoriesInstances方法获取SpringApplicationRunListener.class对象->EventPublishingRunListener对象
    			// EventPublishingRunListener对象初始化时,构造器内会执行下面的逻辑
    				//SimpleApplicationEventMulticaster广播器初始化,并且将listener设置到广播器中
    		// 将上面获取到的EventPublishingRunListener对象对象添加到SpringApplicationRunListeners对象中
    		listeners.starting(); // 解析如下
    		// 调用EventPublishingRunListener对象的starting方法
    			// 将ApplicationStartingEvent广播出去 SimpleApplicationEventMulticaster->multicastEvent方法
    			// 调用getApplicationListeners方法获取所有listeners,然后循环广播
    			// 调用支持事件的listener的listener.onApplicationEvent(event);方法,驱动listener巡行
    			// 此处支持的listener如下
    				// org.springframework.boot.logging.LoggingApplicationListener, 
    				// org.springframework.boot.autoconfigure.BackgroundPreinitializer, 
    				// org.springframework.boot.context.config.DelegatingApplicationListener, 
    				// org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
    		try {
    			ApplicationArguments applicationArguments = new DefaultApplicationArguments(
    					args);
    			// 创建一个DefaultApplicationArguments对象,构造器中构造了一个新的SOURCE对象
    			// 根据SOURCE对象的继承结构->SimpleCommandLinePropertySource->parse方法
    				// 如果args是–开头的,就加入OptionArg中,否则加入到NonOptionArg中
    			// CommandLinePropertySource构造其中commandLineArgs存入source
    			ConfigurableEnvironment environment = prepareEnvironment(listeners,
    					applicationArguments);
    			// 参照下面的prepareEnvironment方法分析
    			configureIgnoreBeanInfo(environment);
    			Banner printedBanner = printBanner(environment); // 打印banner
    			context = createApplicationContext();
    			// 创建applicationContext
    			// 添加AnnotationTypeFilter–>Component 添加AnnotationTypeFilter –> ManagedBean 添加AnnotationTypeFilter –> javax.inject.Named
    			// 
    
    			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);
    		}
    

      

     prepareEnvironment方法分析

    private ConfigurableEnvironment prepareEnvironment(
    			SpringApplicationRunListeners listeners,
    			ApplicationArguments applicationArguments) {
    		// Create and configure the environment
    		ConfigurableEnvironment environment = getOrCreateEnvironment();
    		// 获取或者创建ConfigurableEnvironment 构造environment对象 继承AbstractEnvironment
    		// AbstractEnvironment构造器中调用customizePropertySources方法
    		// StandardEnvironment对象:配置systemEnvironment systemProperties
    		// StandardServletEnvironment对象:配置servletContextInitParams servletConfigInitParams jndiProperties
    		configureEnvironment(environment, applicationArguments.getSourceArgs());
    		// 配置环境的信息
    		// configurePropertySources 配置PropertySources 
    			// commandLineArgs、servletConfigInitParams、servletContextInitParams、jndiProperties(如果存在)、
    			// systemProperties、systemEnvironment、defaultProperties(如果存在)
    		// configureProfiles 配置Profiles
    			// 至于哪个具体的配置文件会被加载,需要在application.properties文件中通过spring.profiles.active属性来设置,其值对应{profile}值。
    			//  application-dev.properties:开发环境  application-test.properties:测试环境 application-prod.properties:生产环境
    		listeners.environmentPrepared(environment);
    		// 通知所有的观察者,发送ApplicationEnvironmentPreparedEvent事件.
    			// org.springframework.boot.context.config.ConfigFileApplicationListener, 
    			// org.springframework.boot.context.config.AnsiOutputApplicationListener, 
    			// org.springframework.boot.logging.LoggingApplicationListener, 
    			// org.springframework.boot.logging.ClasspathLoggingApplicationListener, 
    			// org.springframework.boot.autoconfigure.BackgroundPreinitializer, 
    			// org.springframework.boot.context.config.DelegatingApplicationListener, 
    			// org.springframework.boot.context.FileEncodingApplicationListener
    		// 
    		bindToSpringApplication(environment);
    		if (!this.isCustomEnvironment) {
    			environment = new EnvironmentConverter(getClassLoader())
    					.convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());
    		}
    		ConfigurationPropertySources.attach(environment);
    		return environment;
    	}
    

      

    prepareContext分析
    private void prepareContext(ConfigurableApplicationContext context,
            ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
            ApplicationArguments applicationArguments, Banner printedBanner) {
        // 1. 上下文设置环境
        context.setEnvironment(environment);
        // 2. 调用postProcessApplicationContext方法设置上下文的beanNameGenerator和resourceLoader(如果SpringApplication有的话)
        postProcessApplicationContext(context);
        // 3. 拿到之前实例化SpringApplication对象的时候设置的ApplicationContextInitializer,调用它们的initialize方法,对上下文做初始化
        applyInitializers(context);
        // 4. contextPrepareds 是一个空实现 
        listeners.contextPrepared(context);
        // 5. 打印启动日志
        if (this.logStartupInfo) {
            logStartupInfo(context.getParent() == null);
            logStartupProfileInfo(context);
        }
    
        // Add boot specific singleton beans
        // 6. 日志往上下文的beanFactory中注册一个singleton的bean,bean的名字是springApplicationArguments,bean的实例是之前实例化的ApplicationArguments对象
        context.getBeanFactory().registerSingleton("springApplicationArguments",
                applicationArguments);
        // 如果之前获取的printedBanner不为空,那么往上下文的beanFactory中注册一个singleton的bean,bean的名字是springBootBanner,bean的实例就是这个printedBanner
        if (printedBanner != null) {
            context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);
        }
    
        // Load the sources
        Set<Object> sources = getSources();
        Assert.notEmpty(sources, "Sources must not be empty");
        // 7. 调用load方法注册启动类的bean定义,也就是调用SpringApplication.run(Application.class, args);的类,SpringApplication的load方法内会创建BeanDefinitionLoader的对象,并调用它的load()方法
        load(context, sources.toArray(new Object[sources.size()]));
        // 8. 调用listeners的contextLoaded方法,说明上下文已经加载,该方法先找到所有的ApplicationListener,遍历这些listener,如果该listener继承了ApplicationContextAware类,那么在这一步会调用它的setApplicationContext方法,设置context
        listeners.contextLoaded(context);
    }
    

      

    # Environment Post Processors
    org.springframework.boot.env.EnvironmentPostProcessor=
    org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,
    org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,
    org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor
    

      

    1.SpringFactoriesLoader类

      loadFactoryNames->loadSpringFactories->META-INF/spring.factories

      位置:spring-boot-2.0.5.RELEASE-sources.jar目录下

  • 相关阅读:
    C#编程(七十三)----------浅析C#中内存管理
    C#高级编程小结
    C#编程(七十二)----------DynamicObject和ExpandoObject
    C#编程(七十一)----------DLR ScriptRuntime
    C#编程(七十)----------dynamic类型
    C#编程(六十九)----------DLR简介
    C#编程(六十八)----------LINQ小结
    C#编程(六十七)----------LINQ提供程序
    C#编程(六十六)----------表达式树总结
    python 显示上午下午
  • 原文地址:https://www.cnblogs.com/xiaoyezi/p/9761553.html
Copyright © 2011-2022 走看看