参考文章:SpringBoot启动流程系列讲解
参考视频:SpringBoot启动流程
吐血推荐视频:史上最完整的Spring启动流程
超级好文:SpringBoot执行原理
参考文章:SpringBoot资源接口ResourceLoader和Resource学习
参考文章:到底什么是上下文(Context)
参考文章:超级好文
参考文章:这个系列的文章,让我自愧不如,痛删了原来2W字的内容
文章目录
- Spring Boot启动流程
- 非常重要的函数
- getSpringFactoriesInstances()
- getClassLoader()
- deduceMainApplicationClass()
- getRunListeners(String[] args)
- SpringApplicationRunListeners.starting()
- prepareEnvironment(SpringApplicationRunListeners, applicationArguments)
- prepareContext()
- refreshContext()
- refreshContext().refresh().obtainFreshBeanFactory()
- refreshContext().refresh().finishBeanFactoryInitialization(beanFactory)
- 非常重要的类
- 非常重要的问题
省流
1. 服务构建
- 设置primarySources:YanggxApplication.class
- 设置webType:SERVLET
- 从Spring.factories获取初始化器
- 从Spring.factories获取监听器ApplicationListener
- 设置启动类:YanggxApplication.class
2. 环境准备
- 发布Spring启动事件listeners.starting()
- 封装args参数 new DefaultApplicationArguments(args);
- 配置环境并让环境生效prepareEnvironment() & configureIgnoreBeanInfo()
- 打印Banner图printBanner(environment)
3. 容器创建
- 创建容器createApplicationContext()
- 设置容器prepareContext()
- 刷新容器refreshContext(),包括refresh()和注册钩子
- afterRefresh()自定义接口
- listener.started()
- 执行Runners
- listener.running()
4. 填充容器(就是容器创建的refreshContext().refresh())
- prepareRefresh()刷新前操作,例如:清空缓存、初始化占位符
- obtainFreshBeanFactory()创建BeanFactory
- prepareBeanFactory(beanFactory)设置beanFactory.xxx属性
- postProcessBeanFactory(beanFactory)注册与Servlet相关的特殊Bean,beanDefinition,beanFactory
- invokeBeanFactoryPostProcessors(beanFactory)拓展接口,beanFactoryPostProcessor可以对bean的属性修改
- registerBeanPostProcessors(beanFactory)对Bean实例的增强
- initMessageSource()初始化信息源
- initApplicationEventMulticaster()初始化Application事件发布器
- onRefresh()初始化其他特殊bean
- registerListeners()注册监听器
- finishBeanFactoryInitialization(beanFactory)初始化剩下的Bean,例如用户自定义的Bean
- finishRefresh()完成刷新,发布完成事件
Spring Boot启动流程
服务构建
//SpringApplication类
//只列出几个重要的字段和方法
public class SpringApplication {
//SpringApplication默认web容器类
public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot."
+ "web.servlet.context.AnnotationConfigServletWebServerApplicationContext";
//banner名称,默认为banner.txt
public static final String BANNER_LOCATION_PROPERTY_VALUE = SpringApplicationBannerPrinter.DEFAULT_BANNER_LOCATION;
//banner位置key,默认为spring.banner.location
public static final String BANNER_LOCATION_PROPERTY = SpringApplicationBannerPrinter.BANNER_LOCATION_PROPERTY;
//调用main函数的类,也就是YanggxApplication.class
private Class<?> mainApplicationClass;
//bean名称生成器,执行结果为null
private BeanNameGenerator beanNameGenerator;
//spring的环境,我们使用的是ServletWeb环境
private ConfigurableEnvironment environment;
//web类型,执行结果为SERVLET
private WebApplicationType webApplicationType;
//Application初始化器,springboot启动过程中执行其initialize方法
private List<ApplicationContextInitializer<?>> initializers;
//Application监听器,springboot启动过程执行其onApplicationEvent方法
private List<ApplicationListener<?>> listeners;
/**
* SpringApplication构造函数
* @param resourceLoader 资源加载器的策略接口,传参null,
* @param primarySources 传参YanggxApplication.class
*/
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
//执行结果:null
this.resourceLoader = resourceLoader;
//Set去重:"primarySources":[com.yanggx.spring.YanggxApplication.class]
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
// 判断当前模块web类型:"webApplicationType":"SERVLET"
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 加载Application初始化器
// 获取所有"META-INF/spring.factories"文件中维护的ApplicationContextInitializer子类列表
// org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer
// org.springframework.boot.context.ContextIdApplicationContextInitializer
// org.springframework.boot.context.config.DelegatingApplicationContextInitializer
// org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
// org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
setInitializers((Collection) getSpringFactoriesInstances(
ApplicationContextInitializer.class));
// 3.3 加载Application监听器
// 获取所有"META-INF/spring.factories"文件中维护的ApplicationListener子类列表
// org.springframework.boot.ClearCachesApplicationListener
// org.springframework.boot.builder.ParentContextCloserApplicationListener
// org.springframework.boot.context.FileEncodingApplicationListener
// org.springframework.boot.context.config.AnsiOutputApplicationListener
// org.springframework.boot.context.config.ConfigFileApplicationListener
// org.springframework.boot.context.config.DelegatingApplicationListener
// org.springframework.boot.context.logging.ClasspathLoggingApplicationListener
// org.springframework.boot.context.logging.LoggingApplicationListener
// org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
// org.springframework.boot.autoconfigure.BackgroundPreinitializer
// 加载的这些类都是ApplicationListener的子类
setListeners((Collection) getSpringFactoriesInstances(
ApplicationListener.class));
// 3.4 找到启动类
// 抛出一个RuntimeException,然后通过堆栈信息找到启动类
//"mainApplicationClass": com.yanggx.spring.YanggxApplication.class
this.mainApplicationClass = deduceMainApplicationClass();
}
}
环境准备
public class SpringApplication {
public ConfigurableApplicationContext run(String... args) {
//实例化一个StopWatch实例, 监控项目运行时间
StopWatch stopWatch = new StopWatch();
stopWatch.start();
//初始化Spring上下文
ConfigurableApplicationContext context = null;
//初始化错误报告参数
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
//配置headless,在没有显示器,鼠标,键盘的情况下,仍然可以调用显示,输入输出的方法
configureHeadlessProperty();
//1. 发布Spring启动事件
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting();
try {
/*2. 这一步的主要作用是处理启动类main函数的参数, 将其封装为一个
DefaultApplicationArguments对象, 为prepareEnvironment()提供参数*/
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//3.这一步的主要作用按顺序加载命令行参数, 系统参数和外部配置文件, 创建并配置Web环境
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
configureIgnoreBeanInfo(environment);
//4. 打印Banner图
Banner printedBanner = printBanner(environment);
//....
}
容器创建
public ConfigurableApplicationContext run(String... args) {
//步骤1: 根据switch创建context,分别有:SERVLET、REACTIVE、NONE,并且注册了Bean后置处理器
context = createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
//步骤2: prepareContext()准备context
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
//步骤3: refreshContext()刷新context,BeanDefinition和BeanFactory都是在这里创建的
refreshContext(context);
//步骤4: 刷新完成,该方法是拓展接口,用户可以自定义操作逻辑
afterRefresh(context, applicationArguments);
//步骤6: 发布Application开始事件
listeners.started(context);
//步骤7: 执行Runners,用于调用项目中自定义的执行器xxxRunner类,
//在项目启动完成后立即执行,这些操作只在服务启动时执行一次
callRunners(context, applicationArguments);
//步骤8: 发布Application准备事件
listeners.running(context);
return context;
}
填充容器
/**
* 抽象父类ApplicationContext
*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//刷新前操作,例如:清空缓存、初始化占位符
prepareRefresh();
//获取并刷新beanFactory,创建BeanFactory和BeanDefinition
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//设置beanFactory,配置各种beanFactory.xxx属性
prepareBeanFactory(beanFactory);
//beanFactory的后置处理器:注册与Servlet相关的特殊Bean,注册beanDefinition
postProcessBeanFactory(beanFactory);
/*
BeanFactoryPostProcessor是一个接口, 处理beanFactory中所有的bean,
在所有的beanDefinition加载完成之后, BeanFactoryPostProcessor可以对
beanDefinition进行属性的修改, 之后再进行bean实例化
*/
invokeBeanFactoryPostProcessors(beanFactory);
//beanFactory注册后置处理器,对bean实例的增强
registerBeanPostProcessors(beanFactory);
//初始化messageSource
initMessageSource();
//初始化Application事件发布器
initApplicationEventMulticaster();
//初始化其他特殊的bean,例如实例化了TomcatWebServer
onRefresh();
//注册监听器
registerListeners();
//初始化剩下的Bean,例如用户自定义的bean
finishBeanFactoryInitialization(beanFactory);
//完成刷新,发布完成事件,实例化了所有bean
finishRefresh();
}
}
非常重要的函数
getSpringFactoriesInstances()
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = this.getClassLoader();
Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
//主要获取spring.factories中的key,key对应接口全名
String factoryTypeName = factoryType.getName();
//筛选Map中key为factoryTypeName对应放到list返回
return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
}
//会把Spring.factories文件中所有键值对放到Map中,其实就是缓存
//classLoader参数就是"META-INF/spring.factories"加载器
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
//如果缓存已经有Spring.factories,那就从缓存中拿
MultiValueMap<String, String> result = cache.get(classLoader);
if (result != null) {
return result;
}
//如果缓存中没有Spring.factories,那就从重新加载到缓存
Enumeration<URL> urls = (classLoader != null ?
// FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories"
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;
}
private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes,
ClassLoader classLoader, Object[] args, Set<String> names) {
List<T> instances = new ArrayList<>(names.size());
for (String name : names) {
try {
//通过反射机制创建实例
Class<?> instanceClass = ClassUtils.forName(name, classLoader);
Assert.isAssignable(type, instanceClass);
Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
T instance = (T) BeanUtils.instantiateClass(constructor, args);
instances.add(instance);
}
catch (Throwable ex) {
throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex);
}
}
return instances;
}
总结:
- loadSpringFactories(@Nullable ClassLoader classLoader):判断缓存是否有Spring.factories文件,如果有就提取整个spring.factories。如果没有就加载到缓存再提取。
- loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader):从spring.factories文件中获取指定factoryType
- createSpringFactoriesInstances(Class type, Class<?>[] parameterTypes,
ClassLoader classLoader, Object[] args, Set names):将loadFactoryNames()返回的factoryType,通过反射机制实例化- getSpringFactoriesInstances(Class type, Class<?>[] parameterTypes, Object… args):获取createSpringFactoriesInstances()返回的实例instances,返回实例
getClassLoader()
- 我们都知道java程序写好以后是以.java(文本文件)的文件存在磁盘上,然后,我们通过(bin/javac.exe)编译命令把.java文件编译成.class文件(字节码文件),并存在磁盘上。
但是程序要运行,首先一定要把.class文件加载到JVM内存中才能使用的,我们所讲的classLoader,就是负责把磁盘上的.class文件加载到JVM内存中- 你可以认为每一个Class对象拥有磁盘上的那个.class字节码内容,每一个class对象都有一个getClassLoader()方法,得到是谁把我从.class文件加载到内存中变成Class对象的
deduceMainApplicationClass()
private Class<?> deduceMainApplicationClass() {
try {
//通过一个RuntimeException,获取器堆栈信息
StackTraceElement[] stackTrace = new RuntimeException().getStackTrace();
for (StackTraceElement stackTraceElement : stackTrace) {
if ("main".equals(stackTraceElement.getMethodName())) {
//堆栈中包含main方法,实例化一个该类的对象
return Class.forName(stackTraceElement.getClassName());
}
}
}
catch (ClassNotFoundException ex) { }
return null;
}
getRunListeners(String[] args)
//当前只能获取SpringApplicationRunListener子类列表EventPublishingRunListener
private SpringApplicationRunListeners getRunListeners(String[] args) {
Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
return new SpringApplicationRunListeners(logger, getSpringFactoriesInstances(
SpringApplicationRunListener.class, types, this, args));
}
SpringApplicationRunListeners.starting()
//该SpringApplicationRunListeners存在多个子类,在下面starting方法中,会调用对应子类的starting方法
class SpringApplicationRunListeners {
//发布启动事件
public void starting() {
for (SpringApplicationRunListener listener : this.listeners) {
//目前调用EventPublishingRunListener的starting方法
listener.starting();
}
}
//其他事件都是相同的代码
}
//不仅仅是ApplicationListeners存在很多子类,EventPublishingRunListener也有很多子类
public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {
//SpringApplication对象
private final SpringApplication application;
//命令函参数
private final String[] args;
//事件广播器
private final SimpleApplicationEventMulticaster initialMulticaster;
public EventPublishingRunListener(SpringApplication application, String[] args) {
this.application = application;
this.args = args;
this.initialMulticaster = new SimpleApplicationEventMulticaster();
// 通过application.getListeners(),获取到Listener列表
// ConfigFileApplicationListener
// AnsiOutputApplicationListener
// LoggingApplicationListener
// ClasspathLoggingApplicationListener
// BackgroundPreinitializer
// DelegatingApplicationListener
// ParentContextCloserApplicationListener
// ClearCachesApplicationListener
// FileEncodingApplicationListener
// LiquibaseServiceLocatorApplicationListener
for (ApplicationListener<?> listener : application.getListeners()) {
//将listener添加到事件广播器initialMulticaster
this.initialMulticaster.addApplicationListener(listener);
}
}
@Override
public void starting() {
// 广播器广播ApplicationStartingEvent事件
this.initialMulticaster.multicastEvent(
new ApplicationStartingEvent(this.application, this.args));
}
//其他事件发布都是相同的代码
//...
}
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {
public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event));
//调用父类getApplicationListeners方法
//遍历所有支持ApplicationStartingEvent事件的监听器
//LoggingApplicationListener
//BackgroundPreinitializer
//DelegatingApplicationListener
//LiquibaseServiceLocatorApplicationListener
for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {
//此时的executor为null
Executor executor = getTaskExecutor();
if (executor != null) {
executor.execute(() -> invokeListener(listener, event));
}
else {
//调用listener
invokeListener(listener, event);
}
}
}
}
protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
ErrorHandler errorHandler = this.getErrorHandler();
if (errorHandler != null) {
try {
this.doInvokeListener(listener, event);
} catch (Throwable var5) {
errorHandler.handleError(var5);
}
} else {
this.doInvokeListener(listener, event);
}
}
private void doInvokeListener(ApplicationListener listener, ApplicationEvent event) {
//调用listener的onApplicationEvent方法
listener.onApplicationEvent(event);
}
onApplicationEvent(event){
到这里就不再深究了,这个方法有三十个实现类,操作基本上就是绑定环境,设置参数等等
}
总结:
- SpringApplicationRunListeners.starting()调用了EventPublishingRunListener.starting();
- EventPublishingRunListener.starting()调用了广播器initialMulticaster.multicastEvent()发布SpringApplication启动事件
- initialMulticaster.multicastEvent()分别调用了LoggingApplicationListener、BackgroundPreinitializer、DelegatingApplicationListener、LiquibaseServiceLocatorApplicationListener的invokeListener()方法
invokeListener()——doInvokeListener()——onApplicationEvent()——设置参数、绑定环境等等
prepareEnvironment(SpringApplicationRunListeners, applicationArguments)
private ConfigurableEnvironment prepareEnvironment(
SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments) {
//获取或者创建环境,根据switch判断,选择SERVLET、REACTIVE、NONE类型
ConfigurableEnvironment environment = getOrCreateEnvironment();
//配置环境:为environment配置“共享的类型转换服务”,即:A数据类型变成B数据类型
//然后将defaultProperties和args分别添加到environment的propertySources中
configureEnvironment(environment, applicationArguments.getSourceArgs());
//发布环境准备事件
listeners.environmentPrepared(environment);
//如果指定了main函数,那么会将当前环境绑定到指定的SpringApplication中
bindToSpringApplication(environment);
if (!this.isCustomEnvironment) {
//环境转换:如果environment.class和模块EnvironmentClass()不一致,就转换成一样的
environment = new EnvironmentConverter(getClassLoader())
.convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());
}
//将环境依附到PropertySources
ConfigurationPropertySources.attach(environment);
return environment;
}
prepareContext()
private void prepareContext(ConfigurableApplicationContext context,
ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments, Banner printedBanner) {
//设置context环境:统一ApplicationContext与Application.environment一致
context.setEnvironment(environment);
//设置ApplicationContext.beanNameGenerator、resourceLoader、classLoader、类型转换服务
postProcessApplicationContext(context);
//获取6个初始化器并执行初始化方法,例如设置元数据、配置警告、获取应用名称
applyInitializers(context);
//发布contextPrepared事件
listeners.contextPrepared(context);
if (this.logStartupInfo) {
//配置了info日志
//打印启动和profile日志
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
//获取到DefaultListableBeanFactory实例
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
//注册名为springApplicationArguments,值为applicationArguments的单例bean
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
//banner不为空,那么注册名为springBootBanner,值为printedBanner的单例bean
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
if (beanFactory instanceof DefaultListableBeanFactory) {
//allowBeanDefinitionOverriding默认为false
((DefaultListableBeanFactory) beanFactory)
.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
// 获取sources列表,获取到我们的YanggxApplication.class
Set<Object> sources = getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
//初始化bean加载器,并加载bean到应用上下文
load(context, sources.toArray(new Object[0]));
//发布contextLoaded事件
listeners.contextLoaded(context);
}
refreshContext()
//刷新应用上下文,注册关闭应用钩子
private void refreshContext(ConfigurableApplicationContext context) {
refresh(context);
if (this.registerShutdownHook)
context.registerShutdownHook();
}
/**
* 抽象父类ApplicationContext
*/
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//清空缓存、清空监听器、判断必要属性是否被忽略、打印日志、初始化占位符、设置earlyApplicationEvents
prepareRefresh();
//获取并刷新beanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
/*
配置classLoader为当前context的classLoader
设置BeanExpressionResolver, 解析EL表达式
设置属性编辑器
添加BeanPostProcessor
配置自动装配
手工注册environment相关bean
*/
prepareBeanFactory(beanFactory);
/*
注册basepackages
注册annotatedClasses
注册了request和session两个scopes
注册几个Autowired依赖类
*/
postProcessBeanFactory(beanFactory);
/*
BeanFactoryPostProcessor接口用于增强BeanFactory,
Spring IoC 容器允许 BeanFactoryPostProcessor 在容器实例化任何 bean 之前读取
bean 的定义,并可以修改它。
例如:
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory,
List<BeanFactoryPostProcessor> beanFactoryPostProcessors)
*/
invokeBeanFactoryPostProcessors(beanFactory);
//beanFactory注册后置处理器,对bean实例的增强
registerBeanPostProcessors(beanFactory);
//初始化messageSource
initMessageSource();
//初始化Application事件发布器
initApplicationEventMulticaster();
//初始化其他特殊的bean,例如实例化了TomcatWebServer
onRefresh();
//注册监听器
registerListeners();
//完成beanFactory初始化
finishBeanFactoryInitialization(beanFactory);
//完成刷新,发布完成事件,实例化了所有bean
finishRefresh();
}
}
}
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
protected void prepareRefresh() {
//记录开始时间,调整active状态
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
//初始化占位符,例如:$,#,{}
initPropertySources();
//如果属性中缺少requiredProperties,那么抛出MissingRequiredPropertiesException
getEnvironment().validateRequiredProperties();
//清空监听器
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
//初始化earlyApplicationEvents
this.earlyApplicationEvents = new LinkedHashSet<>();
}
}
refreshContext().refresh().obtainFreshBeanFactory()
/*
refreshBeanFactory():创建beanFactory、指定序列化Id、定制beanFactory、加载bean定义
getBeanFactory():返回beanFactory实例
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//1.初始化beanFactory,并执行加载和解析配置操作
refreshBeanFactory();
//创建BeanFactory,返回beanFactory实例
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
...
@Override
protected final void refreshBeanFactory() throws BeansException {
//判断是否存在beanFactory
if (hasBeanFactory()) {
// 注销所有的单例
destroyBeans();
//重置beanFactory
closeBeanFactory();
}
try {
//创建beanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
//指定序列化id,如果需要的话,让这个BeanFactory从id反序列化到BeanFactory对象
beanFactory.setSerializationId(getId());
//定制BeanFactory
customizeBeanFactory(beanFactory);
//下载BeanDefinitions,放到BeanDefinitionsMap
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
...
}
refreshContext().refresh().finishBeanFactoryInitialization(beanFactory)
/* 根据loadBeanDefinitions加载的BeanDinition到BeanDefinitionMap,
再从BeanDefinitionMap拿出来BeanDefinitionMap创建Bean
*/
createBean(){
//1. createBeanInstance
通过反射机制获取Bean的构造方法,然后创建Bean。
当然,如果构造方法需要参数,就会到单例池中查找。
//2. populateBean
填充Bean属性
//3. 初始化
1. 初始化容器信息,通过invokeAwareMethods(),唤醒各种Aware接口,获取Bean在容器中的信息
2. 初始化Bean成普通对象:通过invokeInitMethods(),执行Bean的初始化方法,这个方法可以通过实现InitialzingBean接口实现的afterPropertiesSet方法。
3. AOP操作Bean成:初始化之前和之后处理各种Bean的后置处理器,即在invokeInitMethods()之前和之后分别执行applyBeanPostProcessorsBeforeInitialization()和applyBeanPostProcessorsAfterInitialization()
//4. 注册销毁
实现了销毁接口DisposableBean,在registerDisposableBean方法注册指定的Bean
在销毁时可以直接执行destroy方法销毁Bean
}
addSingleton(){
将上面create出来的Bean放入单例池就可以获取和使用了
}
非常重要的类
ResourceLoader
//默认的资源加载器
public class DefaultResourceLoader implements ResourceLoader {
@Nullable
private ClassLoader classLoader;
//自定义ProtocolResolver, 用于获取资源
private final Set<ProtocolResolver> protocolResolvers = new LinkedHashSet<>(4);
//
private final Map<Class<?>, Map<Resource, ?>> resourceCaches = new ConcurrentHashMap<>(4);
//实例化ClassLoader
public DefaultResourceLoader() {
this.classLoader = ClassUtils.getDefaultClassLoader();
}
//加载资源
@Override
public Resource getResource(String location) {
Assert.notNull(location, "Location must not be null");
//自定义资源加载方式
for (ProtocolResolver protocolResolver : this.protocolResolvers) {
//调用ProtocolResolver的resolve方法
Resource resource = protocolResolver.resolve(location, this);
if (resource != null) {
//如果获取到资源,立即返回
return resource;
}
}
if (location.startsWith("/")) {
//先判断是否是根目录
return getResourceByPath(location);
}
else if (location.startsWith(CLASSPATH_URL_PREFIX)) {
//再判断是否是classpath下的资源
return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length()), getClassLoader());
}
else {
try {
//先当做一个URL处理
URL url = new URL(location);
//先判断是否是一个file
//不是file的话,再从URL中获取
return (ResourceUtils.isFileURL(url) ? new FileUrlResource(url) : new UrlResource(url));
}
catch (MalformedURLException ex) {
//获取不到资源的话
//当做resource处理
return getResourceByPath(location);
}
}
}
}
非常重要的问题
BeanFactory
BeanFactory BeanFactory定义了IOC容器的最基本形式,并提供了IOC容器应遵守的的最基本的接口,也就是Spring IOC所遵守的最底层和最基本的编程规范。在Spring代码中,BeanFactory只是个接口,并不是IOC容器的具体实现,但是Spring容器给出了很多种实现,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,都是附加了某种功能的实现