SpringBoot 启动类 源码解析 (一 .new SpringApplication 解析)
// * 方法为重要的方法 不加 * 的可以不看 意义不大
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class CmasApplication
{
public static void main(String[] args)
{
// 点击run方法进入
SpringApplication.run(CmasApplication.class, args);
}
}
public class SpringApplication {
// run 方法
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return run(new Class<?>[] { primarySource }, args);
}
// 通过 run 方法进入 1. new了 一个 SpringApplication 对象 2.调用 run 方法
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
// 点击 进入 run 的方法
return new SpringApplication(primarySources).run(args);
}
// run
public ConfigurableApplicationContext run(String... args) {
// 翻译为秒表
StopWatch stopWatch = new StopWatch();
// 进入 start 方法 记录了 当前任务 当前启动时间
stopWatch.start();
// 上下文
ConfigurableApplicationContext context = null;
// 启动异常报告集合:支持自定义 springboot启动错误会进行回调 (看源码的翻译 简洁明了)
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
// 设置jdk系统属性java.awt.headless,默认情况为true即开启 看翻译是和 jdk相关的 不重要
configureHeadlessProperty();
// 获取springboot 启动监听器 进入 getRunListeners 返回 EventPublishingRunListener 监听器 这是是从SpringFactoriesLoader.cache 缓存里获取的
// 还记得 SpringApplication 实例化时 设置监听器和初始化器 把所有文件放到了缓存里吗
// 这是spring-boot 下的 META-INF/spring.factories 文件内的内容 我们可以看到 我们传入的 key 是 SpringApplicationRunListener
// # Run Listeners
// org.springframework.boot.SpringApplicationRunListener=\
// org.springframework.boot.context.event.EventPublishingRunListener
SpringApplicationRunListeners listeners = getRunListeners(args);
// 监听器启动 进行 ApplicationStartingEvent 事件广播
listeners.starting();
try {
// 参数封装,即命令行启动时所传参数,如 --server.port=8080
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// * 准备系统环境 进入方法 listeners 只有一个值就是 EventPublishingRunListener
// 加载外部化配置资源到environment,包括命令行参数、servletConfigInitParams、servletContextInitParams、
//systemProperties、sytemEnvironment、random、application.yml(.yaml/.xml/.properties)等,初始化日志系统。
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
// 配置spring.beaninfo.ignore,并添加到 systemProperties的PropertySource中,默认为true即开启 (跳过)
configureIgnoreBeanInfo(environment);
// 控制台打印图案 (不重要)
Banner printedBanner = printBanner(environment);
// * 创建应用上下文 我们先看到这里
// 对其部分属性:reader、scanner、beanFactory进行了实例化;reader中实例化了属性conditionEvaluator;
context = createApplicationContext();
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
refreshContext(context);
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);
}
return context;
}
public void start(String taskName) throws IllegalStateException {
if (this.currentTaskName != null) {
throw new IllegalStateException("Can't start StopWatch: it's already running");
}
this.currentTaskName = taskName;
this.startTimeNanos = System.nanoTime();
}
// 获取监听器
private SpringApplicationRunListeners getRunListeners(String[] args) {
Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
return new SpringApplicationRunListeners(logger,
getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
}
// 获取 工厂实例 我们发现 这个方法又被调了,在 new SpringApplication 时 设置初始化器和监听器就调用了这个方法
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = getClassLoader();
// Use names and ensure unique to protect against duplicates
Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
// 准备系统环境
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments) {
// 获取或者创建系统环境 进入方法
ConfigurableEnvironment environment = getOrCreateEnvironment();
// 配置PropertySources和activeProfiles
configureEnvironment(environment, applicationArguments.getSourceArgs());
ConfigurationPropertySources.attach(environment);
// ApplicationEnvironmentPreparedEvent 监听器环境准备 进行事件广播(应用环境准备事件)
//和前面的 listeners.starting(); 一样的调用,只是发布的事件不同(ApplicationStartingEvent)
listeners.environmentPrepared(environment);
// 将环境绑定到SpringApplication
bindToSpringApplication(environment);
if (!this.isCustomEnvironment) {
environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
deduceEnvironmentClass());
}
ConfigurationPropertySources.attach(environment);
return environment;
}
// 获取或者创建系统环境
private ConfigurableEnvironment getOrCreateEnvironment() {
if (this.environment != null) {
return this.environment;
}
switch (this.webApplicationType) {
case SERVLET:
return new StandardServletEnvironment(); // 我们知道 webApplicationType = SERVLET 返回 StandardServletEnvironment
case REACTIVE:
return new StandardReactiveWebEnvironment();
default:
return new StandardEnvironment();
}
}
// * 配置环境
protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
if (this.addConversionService) {
ConversionService conversionService = ApplicationConversionService.getSharedInstance();
environment.setConversionService((ConfigurableConversionService) conversionService);
}
// 配置属性资源
configurePropertySources(environment, args);
// 配置 profile
configureProfiles(environment, args);
}
// * 创建应用上下文
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
// 还记得 this.webApplicationType 参数吗,在上面已经看过 是 web应用 this.webApplicationType = SERVLET
// DEFAULT_SERVLET_WEB_CONTEXT_CLASS 是个常量 代码如下:
// public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot." + "web.servlet.context.AnnotationConfigServletWebServerApplicationContext";
// 是个全路径类名 通过反射获取到 AnnotationConfigServletWebServerApplicationContext class
switch (this.webApplicationType) {
case SERVLET:
contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
break;
case REACTIVE:
contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
break;
default:
contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
}
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);
}
}
// 创建 AnnotationConfigServletWebServerApplicationContext 实例对象
return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}
//
public static <T> T instantiateClass(Class<T> clazz) throws BeanInstantiationException {
Assert.notNull(clazz, "Class must not be null");
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
// 获取默认构造器,然后进行实例化
return instantiateClass(clazz.getDeclaredConstructor());
}
catch (NoSuchMethodException ex) {
Constructor<T> ctor = findPrimaryConstructor(clazz);
if (ctor != null) {
return instantiateClass(ctor);
}
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
catch (LinkageError err) {
throw new BeanInstantiationException(clazz, "Unresolvable class definition", err);
}
}
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
// 让构造方法变成可访问的 里面代码较少,代码意思一目了然,我直接复制到这
// if ((!Modifier.isPublic(ctor.getModifiers()) || !Modifier.isPublic(ctor.getDeclaringClass().getModifiers())) && !ctor.isAccessible()) {
// ctor.setAccessible(true);
// }
ReflectionUtils.makeAccessible(ctor);
if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
return KotlinDelegate.instantiateClass(ctor, args);
}
else {
// 代码走这里
Class<?>[] parameterTypes = ctor.getParameterTypes();
// 参数不能比构造器参数多,从调用可知 这里没有参数 所以不进入 for循环
Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
Object[] argsWithDefaultValues = new Object[args.length];
for (int i = 0 ; i < args.length; i++) {
if (args[i] == null) {
Class<?> parameterType = parameterTypes[i];
argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
}
else {
argsWithDefaultValues[i] = args[i];
}
}
// 通过构造器创建对象
return ctor.newInstance(argsWithDefaultValues);
}
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}
}
public final class SpringFactoriesLoader {
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
// 根据类型获取工厂名 也就是全路径的类名 factoryType = ApplicationContextInitializer.class
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
String factoryTypeName = factoryType.getName();
// 进入方法 META-INF/spring.factories 路径下的所有文件 并通过 getOrDefault 方法进行过滤 (containsKey(key) 文件中的key是否包含 factoryTypeName)
return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap<String, String> result = cache.get(classLoader);
if (result != null) {
return result;
}
try {
// classLoader 里面可以获取到已经加载的所有class 类文件 从类文件根据文件名获取 所有 META-INF/spring.factories 路径下的所有文件
Enumeration<URL> urls = (classLoader != null ?
classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
result = new LinkedMultiValueMap<>();
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
for (Map.Entry<?, ?> entry : properties.entrySet()) {
String factoryTypeName = ((String) entry.getKey()).trim();
for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
result.add(factoryTypeName, factoryImplementationName.trim());
}
}
}
cache.put(classLoader, result);
return result;
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load factories from location [" +
FACTORIES_RESOURCE_LOCATION + "]", ex);
}
}
}
// 实例化 AnnotationConfigServletWebServerApplicationContext
public class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContext
implements AnnotationConfigRegistry {
public AnnotationConfigServletWebServerApplicationContext() {
//实例化 注解bean定义读取器 读取 对象注解的 我们知道对象注解一般有 @Bean @Component 等
this.reader = new AnnotatedBeanDefinitionReader(this);
// 实例化类路径bean定义扫描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
}
// 实例化 注解bean定义读取器 AnnotatedBeanDefinitionReader
public class AnnotatedBeanDefinitionReader {
// 实例化
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
// this 调用
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
// * 注册注解配置处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
}
// 看翻译 :用于评估Conditional注释的内部类 说明是用于 @Conditional 条件注解的
class ConditionEvaluator {
public ConditionEvaluator(@Nullable BeanDefinitionRegistry registry,
@Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {
this.context = new ConditionContextImpl(registry, environment, resourceLoader);
}
// 内部类并且实现了ConditionContext
private static class ConditionContextImpl implements ConditionContext {
public ConditionContextImpl(@Nullable BeanDefinitionRegistry registry,
@Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {
this.registry = registry;
// 由返回可知 返回类型为:ConfigurableListableBeanFactory 的工厂
this.beanFactory = deduceBeanFactory(registry);
this.environment = (environment != null ? environment : deduceEnvironment(registry));
this.resourceLoader = (resourceLoader != null ? resourceLoader : deduceResourceLoader(registry));
this.classLoader = deduceClassLoader(resourceLoader, this.beanFactory);
}
@Nullable
private ConfigurableListableBeanFactory deduceBeanFactory(@Nullable BeanDefinitionRegistry source) {
if (source instanceof ConfigurableListableBeanFactory) {
return (ConfigurableListableBeanFactory) source;
}
if (source instanceof ConfigurableApplicationContext) {
return (((ConfigurableApplicationContext) source).getBeanFactory());
}
return null;
}
}
}
public abstract class AnnotationConfigUtils {
// 注册注解配置处理器
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
// 注册注解配置处理器 最终返回了5个实例
// internalConfigurationAnnotationProcessor internalAutowiredAnnotationProcessor
// internalCommonAnnotationProcessor internalEventListenerProcessor internalEventListenerFactory
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
}
总结一下:
1.记录当前任务 当前时间
2.启动监听器 进行 ApplicationStartingEvent 事件广播
3.启动时命令行参数封装,
4.准备系统环境 加载外部化配置资源到environment,包括命令行参数、servletConfigInitParams、servletContextInitParams、systemProperties、sytemEnvironment、random、application.yml(.yaml/.xml/.properties)等,初始化日志系统
5.配置spring.beaninfo.ignore,并添加到 systemProperties的PropertySource中
6.控制台打印图案
7.创建应用上下文,对其部分属性:reader、scanner、beanFactory进行了实例化;reader中实例化了属性conditionEvaluator;