import org.springframework.boot.SpringApplication;//启动类
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication//启动必要的注解
public class SpringBootDemoApplication {
//运行main方法启动springBoot
public static void main(String[] args) {
SpringApplication.run(SpringBootDemoApplication.class, args);//启动类的静态run方法
}
}
2.初始化配置
main方法调用run方法又调用了启动类中的另一个静态run方法,通过实例化一个SpringApplication对象再次调用run方法
public static ConfigurableApplicationContext run(Class>[] primarySources, String[] args) {
return new SpringApplication(primarySources).run(args);//实例化一个SpringApplication对象
}
在实例化SpringApplication对象时,在构造函数中通过类加载器,加载classpath类路径下的多个jar包里的spring.factories配置文件,根据配置文件来创建一些初始配置对象,并创建了监听器对象
//构造方法
public SpringApplication(ResourceLoader resourceLoader, Class>... primarySources) {
//。。。。。。。。。。
//(loadFactories)读取classpath下所有的spring.factories配置文件
// 配置应用程序启动前的初始化对象
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 配置应用程序启动前的监听器
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
配置应用程序启动前的初始化对象步骤
getSpringFactoriesInstances()
获取初始化类的类名
通过类名实例化对象
读取运行环境中所有meta-INF/spring.factories配置
3.执行run方法public ConfigurableApplicationContext run(String... args) {
//。。。。。。。。。
//通知监听器
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
//1,创建应用程序环境对象,读取用户配置文件(application.properties application.yaml)
ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
//2,创建应用程序上下文,在此处也创建了beanfactory
context = createApplicationContext();
//3,刷新应用程序上下文(启动的核心)
refreshContext(context);
//4,启动完成通知监听器
listeners.started(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, listeners);
throw new IllegalStateException(ex);
}
try {
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, null);
throw new IllegalStateException(ex);
}
return context;
}
创建应用程序上下文
在初始化和配置环境之后,开始创建应用程序上下文,creatApplicationContext();关键的工厂BeanFatory在此时创建,默认创建的是org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext对象
创建工厂对象
刷新应用上下文创建好应用程序上下文后,开始刷新上下文refreshContext();实现工厂配置,bean处理器配置,类的扫描,bean定义,bean类信息缓存,服务器创建,bean实例化,动态代理对象创建。
spring中的注册bean信息和实力化bean信息是两件事
注册bean信息不是创建bean 对象,而是解析bean类来获取详细信息,创建BeanDefination对象,携带bean类的字节码和方法等信息,把BeanDefinition对象保存到工厂的BeanDefinitionMap
工厂实例化Bean时,直接BeanDefinitionMap.get(beanName)获取bean的字节码信息,通过反射创建对象
配置工厂对象beanFactory:包括上下文类加载器,bean工厂发布处理器
注册并实例化bean工厂发布处理器,并调用他们
注册并实例化Bean发布处理器:rigisterBeanPostProcessors
bean发布处理器生产AOP代理对象
初始化一些与上下文有特别关系的bean对象
默认tomacat服务器的创建就是此方法完成,此处定义特别的bean创建,一般是服务器有关或个性化对象
实例化所有Bean工厂缓存的Bean对象
服务器启动后,创建spring工厂里面缓存的bean 信息
发布通知—通知上下文刷新完成
通知监听者—启动程序完成
总结:
1.run方法中去创建一个SpringApplication 实例,在构造方法内,可以发现其调用一个初始化的Initialize方法,为SpringApplication对象赋初值
2.创建应用的监听器SpringApplicationRunListeners并开始监听
3.加载SpringBoot配置环境(ConfigurableEnvironment),如果是通过web容器发布,会加载StandardEnvironment,其最终也是继承了ConfigurableEnvironment
4.配置环境加入到监听器对象中
5.创建run方法的返回对象,ConfigurableApplication(应用配置上下文),
方法会先获取显式设置的应用上下文(applicationContextClass),如果不存在,再加载默认的环境配置,默认选择AnnotationConfigApplicationContext注解上下文,最后通过BeanUnils实例化上下文对象,并返回。
6.回到run方法内,prepareContext方法将Listeners、environment、applicationArguments、banner等重要组件与上下文对象关联
7.接下来的refreshContext方法将实现spring-boot-starter-*(mybatis、redis等)自动化配置的关键,包括spring.factories的加载,bean的实例化等核心工作
8.refesh方法:配置结束后,Springboot做了一些基本的收尾工作,返回了应用环境上下文,回顾整体流程,Springboot的启动,主要创建了配置环境,事件监听、应用上下文(applicationContext),并基于以上条件,在容器中开始实例化需要的Bean,通过SpringBoot启动的程序已经构造完成。



