配置IOC容器
public ConfigurableApplicationContext run(String... args) {
// -- snip
try {
// context的类型是AnnotationConfigServletWebServerApplicationContext
context = createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
// 1. 准备容器
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
// 2. 刷新容器
refreshContext(context);
afterRefresh(context, applicationArguments);
startup.started();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), startup);
}
listeners.started(context, startup.timeTakenToStarted());
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
throw handleRunFailure(context, ex, listeners);
}
try {
if (context.isRunning()) {
listeners.ready(context, startup.ready());
}
}
catch (Throwable ex) {
throw handleRunFailure(context, ex, null);
}
return context;
}
1. 准备容器
private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context,
ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments, Banner printedBanner) {
context.setEnvironment(environment);
// 配置容器的类加载器、资源加载器、类型转换器
postProcessApplicationContext(context);
// 如果JVM允许AOT,则配置AOT相关的ApplicationContextInitializer
// AOT(ahead of time)是在程序运行前将字节码编译成机器码,JIT(just in time)是程序边运行边将字节码编译成机器码。普通SpringBoot用的是JIT
addAotGeneratedInitializerIfNecessary(this.initializers);
// 1. 执行初始化器
applyInitializers(context);
listeners.contextPrepared(context);
// 关闭引导上下文
bootstrapContext.close(context);
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
// Add boot specific singleton beans
// beanFactory的类型是DefaultListableBeanFactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// 向bean工厂注册单例applicationArguments
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
if (beanFactory instanceof AbstractAutowireCapableBeanFactory autowireCapableBeanFactory) {
// 配置是否允许循环依赖
autowireCapableBeanFactory.setAllowCircularReferences(this.allowCircularReferences);
if (beanFactory instanceof DefaultListableBeanFactory listableBeanFactory) {
listableBeanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
}
if (this.lazyInitialization) {
// 设置延迟加载
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
if (this.keepAlive) {
// KeepAlive()对象额外启动一个非守护线程,避免`SpringBoot`因为非守护线程结束而关闭JVM
context.addApplicationListener(new KeepAlive());
}
// PropertySourceOrderingBeanFactoryPostProcessor是对@PropertySource注解修饰的类进行排序
context.addBeanFactoryPostProcessor(new PropertySourceOrderingBeanFactoryPostProcessor(context));
if (!AotDetector.useGeneratedArtifacts()) {
// Load the sources
Set<Object> sources = getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
load(context, sources.toArray(new Object[0]));
}
listeners.contextLoaded(context);
}
1. 执行初始化器
protected void applyInitializers(ConfigurableApplicationContext context) {
for (ApplicationContextInitializer initializer : getInitializers()) {
Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),
ApplicationContextInitializer.class);
Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
initializer.initialize(context);
}
}
SpringBoot
默认的初始化器有7个。从上到下它们的功能分别是
0. 执行环境属性context.initializer.classes
指定的初始化器。它的优先级最高。
- 向容器添加一个
CachingMetadataReaderFactoryPostProcessor
。 - 初始化容器的ID。
- 向容器增加一个处理错误告警的BeanFactoryPostProcessor。
RSocket
是基于Reactive Streams
的通信协议。- 向容器配置
server.port
端口属性。 - 向容器中配置ConditionEvaluationReportListener。
2.刷新容器
最终调用的是AbstractApplicationContext#refresh()
方法。
private final Lock startupShutdownLock = new ReentrantLock();
public void refresh() throws BeansException, IllegalStateException {
// startupShutdownLock锁是防止当前线程刷新容器,别的线程关闭容器。
this.startupShutdownLock.lock();
try {
this.startupShutdownThread = Thread.currentThread();
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
// 1. 准备刷新
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 2. 重获容器
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 3. 配置容器
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 4. 容器子类添加后处理器
postProcessBeanFactory(beanFactory);
// 标记阶段
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
// 5. 调用BeanFactory后处理器
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 6. 注册bean后处理器
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
// 向bean工厂注册一个名为`messageSource`的单例bean
initMessageSource();
// Initialize event multicaster for this context.
// 向bean工厂注册一个名为`applicationEventMulticaster`的SimpleApplicationEventMulticaster对象
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 7. tomcat初始化
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (RuntimeException | Error ex ) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
contextRefresh.end();
}
}
finally {
this.startupShutdownThread = null;
this.startupShutdownLock.unlock();
}
}
1. 准备刷新
protected void prepareRefresh() {
// Switch to active.
this.startupDate = System.currentTimeMillis(); // startupDate的类型是`long`,标记容器启动时刻
this.closed.set(false); // close的类型是`AtomicBoolean`,标记当前容器是否已就绪
this.active.set(true); // active的类型是`AtomicBoolean`,标记当前容器是否活跃
// 源码此处有log
// Initialize any placeholder property sources in the context environment.
// 初始化名称为`servletContextInitParams`的ServletContextPropertySource`,即初始化Servlet相关属性
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
// earlyApplicationListeners 刷新容器之前已存在的监听器
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
}
2. 重获容器
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
// 当前applicationContext是容器对象,但是包含了环境配置,事件发布器等等。而`getBeanFactory`返回的容器仅仅处理对象
return getBeanFactory();
}
// GenericApplicationContext#refreshBeanFactory
protected final void refreshBeanFactory() throws IllegalStateException {
// refreshed的类型是`AtomicBoolean`,代表容器正在刷新,cas表示容器只能刷新一次
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
// 容器的id是`application`
this.beanFactory.setSerializationId(getId());
}
3. 配置容器
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
// 设置bean的类加载器,是`AppClassLoader`
beanFactory.setBeanClassLoader(getClassLoader());
// 设置SPEL解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
// 设置属性编辑器,将字符串属性转为java对象,比如将"false"字符串转为Boolean.False。
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
// 配置bean后处理器。`ignoreDependencyInterface`表示容器不解析这些接口,不将接口的实现放入容器。
//源码里是将这些接口放入`Set<Class<?>> ignoredDependencyInterfaces`。
// 这些接口统一由`ApplicationContextAwareProcessor`处理。
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
// 指定BeanFactory.class接口的容器对象是beanfactory
// 源码里就是将`BeanFactory.class`和`beanFactory`放入`Map<Class<?>, Object> resolvableDependencies`。
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
// 添加bean后处理器,ApplicationListenerDetector监听实现ApplicationListener接口的bean
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
// NativeDetector检测当前环境是否是GraalVM native镜像。
if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
// 向容器注册名为"environment"的单例ApplicationServletEnvironment对象
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
// 向容器注册名为"systemProperties"的单例Properties对象
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
// 向容器注册名为"systemEnvironment"的`UnmodifiableMap`对象
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
// 向容器注册名为"applicationStartup"的单例DefaultApplicationStartup对象
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}
4. 容器子类添加后处理器
ServletWebServerApplicationContext
是容器实现类,它添加bean后处理器。WebApplicationContextServletContextAwareProcessor
是向容器添加servletContext
。
// org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
registerWebApplicationScopes();
}
5. 调用BeanFactory后处理器
最终调用的是PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors()
方法。后处理器分2种,一种是BeanDefinitionRegistryPostProcessors
,处理BeanDefinitionRegistry
中登记的BeanDefinition
。BeanDefinition
是bean的定义类,是对不同来源(Annotation
注解,xml
文件)的容器定义(scope
, beanName
)的抽象。容器根据定义类创建容器。一种是BeanFactoryPostProcessors
,处理容器。
先看BeanDefinitionRegistryPostProcessors
。首先处理PriorityOrdered
接口,之后处理Ordered
接口,其余的最后处理。
invokeBeanDefinitionRegistryPostProcessors
方法让每个后处理器postProcessor
调用自己的postProcessBeanDefinitionRegistry
方法。其中有个org.springframework.context.annotation.ConfigurationClassPostProcessor
将所有@Confuguration
注解类解析成BeanDefinitionHolder
。
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process")
.tag("postProcessor", postProcessor::toString);
postProcessor.postProcessBeanDefinitionRegistry(registry);
postProcessBeanDefRegistry.end();
}
}
BeanFactoryPostProcessors
也是按照优先级进行处理。
处理结束后,删除缓存。
@Override
public void clearMetadataCache() {
super.clearMetadataCache();
this.mergedBeanDefinitionHolders.clear();
clearByTypeCache();
}
6. 注册bean后处理器
registerBeanPostProcessors
方法也是按照优先级注册bean
后处理方法。这里的注册指的是将BeanPostProcessors
放入容器,即abstractBeanFactory.addBeanPostProcessors(postProcessors)
。而不是执行BeanPostProcessors
,因为此时还没有创建bean。
最后将后处理器重新注册一遍。并且添加ApplicationListenerDetector
容器后处理器。
7. tomcat初始化
onfresh()
是交给容器子类自定义初始化,web容器在此配置web环境并且启动tomcat。