springboot启动流程源码分析以及自定义starter

几个重要的时间回调机制

配置在META-INF/spring.factories

ApplicationContextlnitializer

SpringApplicationRunListener

只需要放在ioc容器中

ApplicationRunner

CommandLineRunner

 

1、创建SpringApplcaiton对象

@SuppressWarnings({ "unchecked", "rawtypes" })
public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
	this.resourceLoader = resourceLoader;
	Assert.notNull(primarySources, "PrimarySources must not be null");
	this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
	
    //判断是否是一个web应用
    this.webApplicationType = WebApplicationType.deduceFromClasspath();
	
    //从类路径下找到META-INF/spring.factories配置的所有ApplicationContextInitializer;
    //然后保存起来
    setInitializers((Collection) getSpringFactoriesInstances(
			ApplicationContextInitializer.class));

    //从类路径下找到META-INF/spring.factories配置的所有ApplicationListener
	setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));

    //从多个配置类中找到有main方法的主配置类
	this.mainApplicationClass = deduceMainApplicationClass();
}

2、run(args);

public ConfigurableApplicationContext run(String... args) {
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
        
        //ioc容器
		ConfigurableApplicationContext context = null;
		Collection exceptionReporters = new ArrayList<>();
		configureHeadlessProperty();
	       
        //获取SpringApplicationRunListeners,从类路径下找到META-INF/spring.factories
       	SpringApplicationRunListeners listeners = getRunListeners(args);
		
        //回调所有的SpringApplicationRunListener.starting()方法
        listeners.starting();

		try {

            //封装命令行参数
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(
					args);

            //准备环境
			ConfigurableEnvironment environment = prepareEnvironment(listeners,
					applicationArguments);
            //创建环境完成后回调SpringApplicationRunListener.environmentPrepared();
            //表示环境准备完成
             
			configureIgnoreBeanInfo(environment);
            
            //打印Banner
			Banner printedBanner = printBanner(environment);

            //创建ApplicationContext;决定创建web的ioc还是普通的ioc
			context = createApplicationContext();
			
            //异常
            exceptionReporters = getSpringFactoriesInstances(
					SpringBootExceptionReporter.class,
					new Class[] { ConfigurableApplicationContext.class }, context);
			
            //准备上下文环境,将environment保存到ioc中,而且applyInitializers()
            //applyInitializers();回调之前保存的所有的
            //ApplicationContextInitializer的intialize方法
            
            //回调所有的SpringApplicationRunListener的contextPrepared()     
            prepareContext(context, environment, listeners, applicationArguments,
					printedBanner);
            //prepareContext运行完成以后回调所有的SpringApplicationRunListener的
            //contextLoaded();
            
            //刷新容器:ioc容器初始化(如果是web应用还会创建嵌入式的tomcat),Spring注解版
            //扫描、创建、加载所有组件的地方(配置类、组件、自动配置)
			refreshContext(context);

            //从ioc容器中获取所有的ApplcationRunner和CommandLineRunner进行回调
            //ApplcationRunner先回调,CommandLineRunner在调用
			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);
		}
        //整个springboot应用启动完成以后返回启动的ioc容器
		return context;
	}

springboot自定义starter

starter

1)、这个场景需要使用到的依赖是扫描

2)、如何编写自动配置

 

你可能感兴趣的:(springboot)