注解
在Spring Boot入口类里,会在类名上加@EnableAutoConfiguration或者@SpringBootApplication注解,这两个有什么差别呢?
@EnableAutoConfiguration
@EnableAutoConfiguration注解的源码:
@SpringBootApplication
|
|
可以看出@SpringBootApplication
相当于是@Configuration
,@EnableAutoConfiguration
,@ComponentScan
这三者的结合。@SpringBootApplication
也提供了后面两个注解配置的别名(alias)。
例如exclude
排除的类,scanBasePackages
扫描的包名等,这些都可以直接该注解上进行配置。
程序入口类SpringApplication
|
|
Spring Boot入口程序很简单,直接通过静态的SpringApplication.run就运行了,返回ConfigurableApplicationContext对象。
进入run方法里,可以很直观看到,启动程序主要做两部分,一个是initialize()初始化所有配置参数,另外一个是run()方法。
initialize()
|
|
- deduceWebEnvironment()判断是否有Web环境,主要通过判断是否同时存在
javax.servlet.Servlet
和org.springframework.web.context.ConfigurableWebApplicationContext
这两个类 - getSpringFactoriesInstances()是从所有jar中含有
META-INF/spring.factories
,从该文件里读取配置信息。 - setInitializers()读取所有
ApplicationContextInitializer
类型的类,放在List<ApplicationContextInitializer<?>> initializers
这个列表里。 - setListeners()读取所有
ApplicationListener
类型的类,放在List<ApplicationListener<?>> listeners
这个列表里。
getSpringFactoriesInstances()
|
|
- SpringFactoriesLoader.loadFactoryNames从
META-INF/spring.factories
配置文件,获取类型为type的类名。 - createSpringFactoriesInstances根据类名,创建实例对象。
loadFactoryNames()
|
|
获取所有jar包的META-INF/spring.factories文件,这个文件是一个properties型的配置文件。
根据factoryClassNames从配置文件里获取factoryClassNames,有可能是多个类名。所以调用StringUtils.commaDelimitedListToStringArray转成数组
Spring-Boot-1.5.4.RELEASE.jar里的META-INF/spring.factories文件信息
run()
上面的initialize()方法只是载入配置信息,没有执行任何Spring相关的调用,而run()才是真正的通过配置运行程序。
- SpringApplicationRunListeners listeners = getRunListeners(args);这段也是从META-INF/spring.factories载入SpringApplicationRunListener型的类。
- ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);这段是从运行环境获取参数,例如:activeProfiles,SystemEnvironment,SystemProperties等。
- createApplicationContext(),根据是否为web环境,创建不同的ApplicationContext。
- analyzers = new FailureAnalyzers(context)从META-INF/spring.factories载入FailureAnalyzer型的类,抛异常时的处理
- prepareContext,触发所有Initializer和Linstener(这两种类型的对象来自于spring.factories)
printBanner()
打印Spring Boot的logo
|
|
prepareContext()
|
|
prepareContext主要有两大处理
- applyInitializers触发所有ApplicationContextInitializer类的initialize()方法
- listeners.contextLoaded(context)// 触发所有SpringApplicationRunListeners的contextLoaded事件
refresh()
载入Spring Bean,相当于Spring容器启动做的一些处理的,比如prepareBeanFactory(),postProcessBeanFactory(),registerBeanPostProcessors等。
具体的可以了解Spring的启动流程。
参考资料
- Spring Boot 1.5.4.RELEASE源码