Spring Boot

    Spring Boot的初始化时从一个main方法开始,进入调用到SpringApplication的内部去实现java

 

首先调用的是web

 

进入这个类的内部就是spring

继续tomcat

核心就是从这个new方法开始,run(args)开始执行各类初始化环境的操做springboot

 

首先咱们来看这个构造方法app

 

这个方法调用的是initialize方法区初始化各类须要的条件环境less

private void initialize(Object[] sources) {
		if (sources != null && sources.length > 0) {
			this.sources.addAll(Arrays.asList(sources));
		}
//经过判断是否能加载到Servlate跟ConfigurableWebApplicationContext这个类去判读是否为web环境
		this.webEnvironment = deduceWebEnvironment();
//读取spring.factories文件中的org.springframework.context.ApplicationContextInitializer对应的各类类名,而后加载内存建立好,为了下面使用
		setInitializers((Collection) getSpringFactoriesInstances(
				ApplicationContextInitializer.class));
//读取spring.factories文件中的org.springframework.context.ApplicationListener对应的各类类名,而后加载内存建立好,为了下面使用
	setListeners((Collection)getSpringFactoriesInstances(ApplicationListener.class));
//肯定main方法所在的类
		this.mainApplicationClass = deduceMainApplicationClass();
	}

以一个方法为例子this

private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type,
      Class<?>[] parameterTypes, Object... args) {
//取得上下文加载器
   ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
   // Use names and ensure unique to protect against duplicates
//这是根据spring.facotories文件获得的value都是一些SpringApplicationRunListener的实现类的全类名称
   Set<String> names = new LinkedHashSet<String>(
         SpringFactoriesLoader.loadFactoryNames(type, classLoader));
//加载到内存并初始化实例
   List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
         classLoader, args, names);
//根据实例的名称排序
   AnnotationAwareOrderComparator.sort(instances);
   return instances;
}

值得小注意的是:Spring使用的是线程上下文加载器,去加载的本身的各个模块的jar中的类,由于为了确保加载器必定是当前容器的加载器,才能够加在到这些Class文件的,好比当前的环境是web环境,并且是tomcat的容器,因此这些jar文件是经过的tomcat的的类加载去加载的,而默认的线程上下文加载就是自定义的tomcat容器加载器,因此须要这样去加载Class,其实就是经过类加载器能够更换咱们想要的加载器spa

下面就是简单的根据ClassLoader还有Class类型去加载类文件到内存,而后实例化的过程,而后返回这些实例对象线程

当须要的ApplicationContextInitializer、ApplicationListener实现类加载完成后,都会保存到SpringApplication这个类的对应的Map中

//保存ApplicationContextInitializer实现类的实例对象
public void setInitializers(
			Collection<? extends ApplicationContextInitializer<?>> initializers) {
		this.initializers = new ArrayList<ApplicationContextInitializer<?>>();
		this.initializers.addAll(initializers);

	}
//保存ApplicationListener实现类的的实例对象
public void setListeners(Collection<? extends ApplicationListener<?>> listeners) {
		this.listeners = new ArrayList<ApplicationListener<?>>();
		this.listeners.addAll(listeners);
	}

 

大概加载流程以下

至此springboot创造一个SpringApplication这个类,准备了实例化各类配置参数类,而后进入到真正的建立SpringContext整个环境的入口

public ConfigurableApplicationContext run(String... args) {
//建立一个监听类StopWacht,记录启动的时间,加载类等信息输出到log
		StopWatch stopWatch = new StopWatch();
		stopWatch.start();

		ConfigurableApplicationContext context = null;
		FailureAnalyzers analyzers = null;
//用来设置java.awt.headless 属性是true 仍是false,是J2SE的一种模式用于在缺乏显示屏、键盘    
    //或者鼠标时的系统配置
		configureHeadlessProperty();
//读取spring.factory中配置初始化EventPublishingRunListener这个类
		SpringApplicationRunListeners listeners = getRunListeners(args);
//发送启动事件到对应的各个监听器中
		listeners.starting();
		try {
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(
					args);
			ConfigurableEnvironment environment = prepareEnvironment(listeners,
					applicationArguments);
			Banner printedBanner = printBanner(environment);
			context = createApplicationContext();
			analyzers = new FailureAnalyzers(context);
			prepareContext(context, environment, listeners, applicationArguments,
					printedBanner);
			refreshContext(context);
			afterRefresh(context, applicationArguments);
			listeners.finished(context, null);
			stopWatch.stop();
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass)
						.logStarted(getApplicationLog(), stopWatch);
			}
			return context;
		}
		catch (Throwable ex) {
			handleRunFailure(context, listeners, analyzers, ex);
			throw new IllegalStateException(ex);
		}
	}
相关文章
相关标签/搜索