标签:except 完成 swa utils slist autoconf 源码 赋值 clu
上一篇分析了@SpringBootApplication注解,接下来从SpringApplication.run(Application.class, args);代码开始一行行DEBUG进行分析
1 @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) 2 public class Application { 3 public static void main(String[] args) { 4 SpringApplication.run(Application.class, args); 5 } 6 }
1 public static ConfigurableApplicationContext run(Object source, String... args) { 2 return run(new Object[] { source }, args); 3 }
1 public static ConfigurableApplicationContext run(Object[] sources, String[] args) { 2 return new SpringApplication(sources).run(args); 3 }
最终会创建一个SpringApplication的对象,然后调用它的run方法
1 public SpringApplication(Object... sources) { 2 initialize(sources); 3 }
SpringApplication的构造函数会调用initialize方法进行初始化
1 @SuppressWarnings({ "unchecked", "rawtypes" }) 2 private void initialize(Object[] sources) { 3 if (sources != null && sources.length > 0) { 4 this.sources.addAll(Arrays.asList(sources)); 5 } 6 this.webEnvironment = deduceWebEnvironment(); 7 setInitializers((Collection) getSpringFactoriesInstances( 8 ApplicationContextInitializer.class)); 9 setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); 10 this.mainApplicationClass = deduceMainApplicationClass(); 11 }
首先,会把sources参数(也就是com.dylan.java.springboot.template.Application的class对象)添加到SpringApplication对象的sources属性,该属性是一个LinkedHashSet类型,然后接下来的一行调用了deduceWebEnvironment方法
1 private boolean deduceWebEnvironment() { 2 for (String className : WEB_ENVIRONMENT_CLASSES) { 3 if (!ClassUtils.isPresent(className, null)) { 4 return false; 5 } 6 } 7 return true; 8 }
1 private static final String[] WEB_ENVIRONMENT_CLASSES = { "javax.servlet.Servlet", 2 "org.springframework.web.context.ConfigurableWebApplicationContext" };
该方法会调用ClassUtils类的isPresent方法,检查classpath中是否存在javax.servlet.Servlet类和org.springframework.web.context.ConfigurableWebApplicationContext类,并赋值给SpringApplication对象的webEnvironment属性,该属性是一个boolean类型,表示启动的程序是否是一个web应用程序
接下来是第7行,主要是初始化ApplicationContextInitializer
在classpath下的JAR文件中包含的/META/spring.factories文件里找到org.springframework.context.ApplicationContextInitializer对应的属性,然后实例化并排序,设置到SpringApplication对象的initializers属性,该属性是一个ArrayList类型
接下来是第8行,主要是初始化ApplicationListener
在classpath下的JAR文件中包含的/META/spring.factories文件里找到org.springframework.context.ApplicationListener对应的属性,然后实例化并排序,设置到SpringApplication对象的listeners属性,该属性是一个ArrayList类型
最后调用deduceMainApplicationClass方法找到main函数所在的类,实现的方式是获取当前方法调用栈,找到main函数的类,并设置到SpringApplication对象的mainApplicationClass属性,该属性是一个Class类型
1 private Class<?> deduceMainApplicationClass() { 2 try { 3 StackTraceElement[] stackTrace = new RuntimeException().getStackTrace(); 4 for (StackTraceElement stackTraceElement : stackTrace) { 5 if ("main".equals(stackTraceElement.getMethodName())) { 6 return Class.forName(stackTraceElement.getClassName()); 7 } 8 } 9 } 10 catch (ClassNotFoundException ex) { 11 // Swallow and continue 12 } 13 return null; 14 }
至此,SpringApplication的初始化完成
SpringBoot(1.5.6.RELEASE)源码解析(二)
标签:except 完成 swa utils slist autoconf 源码 赋值 clu
原文地址:http://www.cnblogs.com/dylan-java/p/7455290.html