springboot启动分析

springboot启动分析

一、启动类 

	@SpringBootApplication
	public class SpringBootStudyApplication {

		public static void main(String[] args) {
			// spring boot 启动入口
			SpringApplication.run(SpringBootStudyApplication.class, args);
		}

	}

 二、实例化SpringApplication对象

	// org.springframework.boot.SpringApplication.SpringApplication
	// SpringApplication的静态run方法,进入重载方法run
	public static ConfigurableApplicationContext run(Class<?> primarySource,
			String... args) {
		return run(new Class<?>[] { primarySource }, args);
	}
	
	// 实例化SpringApplication对象,然后调用成员方法run(args)
	public static ConfigurableApplicationContext run(Class<?>[] primarySources,
			String[] args) {
		return new SpringApplication(primarySources).run(args);
	}
	// 进入构造器重载方法
	public SpringApplication(Class<?>... primarySources) {
		this(null, primarySources);
	}
	// 实例化SpringApplication
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
		this.resourceLoader = resourceLoader;
		Assert.notNull(primarySources, "PrimarySources must not be null");
		// 将配置的class保存起来
		this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
		// 自动推断出webApplication容器的类型(servlet)
		this.webApplicationType = WebApplicationType.deduceFromClasspath();
		// 从META-INF/spring.factories文件中读取ApplicationContextInitializer实现类,并且实例化(ApplicationContextInitializer接口在spring-context包下,只有一个抽象方法,可以在spring容器refresh刷新前进行一些其他操作)
		setInitializers((Collection) getSpringFactoriesInstances(
				ApplicationContextInitializer.class));
		// 从META-INF/spring.factories文件中读取ApplicationListener实现类
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		// 从参数primarySources数组中推断出存在main方法的class
		this.mainApplicationClass = deduceMainApplicationClass();
	}


三、调用SpringApplication的run(args)方法 

AbstractApplicationContext.refresh()分析

	/**
	 * Run the Spring application, creating and refreshing a new
	 * {@link ApplicationContext}.
	 * @param args the application arguments (usually passed from a Java main method)
	 * @return a running {@link ApplicationContext}
	 */
	public ConfigurableApplicationContext run(String... args) {
		// 开始计时
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
		configureHeadlessProperty();
		// 从META-INF/spring.factories文件中获取SpringApplicationRunListener实现类,并且实例化
		//(SpringApplicationRunListener实现类必须要有一个带参的构造器,参数列表是:SpringApplication application, String[] args),
		// listeners保存了SpringApplicationRunListener集合
		SpringApplicationRunListeners listeners = getRunListeners(args);
		// 该方法其实调用的是遍历SpringApplicationRunListener的同名方法starting()
		listeners.starting();
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(
					args);
			// 准备配置环境
			ConfigurableEnvironment environment = prepareEnvironment(listeners,
					applicationArguments);
			// 忽视一些bean类
			configureIgnoreBeanInfo(environment);
			// 打印banner图标
			Banner printedBanner = printBanner(environment);
			// 根据前面构造器方法中推断出的容器类型来创建ApplicationContext容器
			context = createApplicationContext();
			// 从spring.factories文件中获取异常报告器,根据参数进行实例化
			exceptionReporters = getSpringFactoriesInstances(
					SpringBootExceptionReporter.class,
					new Class[] { ConfigurableApplicationContext.class }, context);
			// 准备context容器,会调用ApplicationContextInitializer实现类的initial方法
			prepareContext(context, environment, listeners, applicationArguments,
					printedBanner);
   			// 会调用AbstractApplicationContext的refresh()方法
			refreshContext(context);
			// 容器刷新后处理,默认空方法,让子类进行实现
			afterRefresh(context, applicationArguments);
			// 统计运行的时间,进行打印日志
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass)
						.logStarted(getApplicationLog(), stopWatch);
			}
			// 遍历调用SpringApplicationRunListener的started(context)方法
			listeners.started(context);
			// 调用ApplicationRunner和CommandLineRunner的run方法
			callRunners(context, applicationArguments);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, listeners);
			throw new IllegalStateException(ex);
		}

		try {
			// 遍历调用SpringApplicationRunListener的started(context)方法
			listeners.running(context);
		}
		catch (Throwable ex) {
			handleRunFailure(context, ex, exceptionReporters, null);
			throw new IllegalStateException(ex);
		}
		return context;
	}
发布了53 篇原创文章 · 获赞 10 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/blog_zxb/article/details/101714867
今日推荐