Spring Boot 源码分析(四)
应用上下文
刷新容器
refreshContext(context);
内部实现:
private void refreshContext(ConfigurableApplicationContext context) {
if (this.registerShutdownHook) {
try {
// 注册钩子函数,当shutdown时,执行。
context.registerShutdownHook();
}
catch (AccessControlException ex) {
// Not allowed in some environments.
}
}
// 主要进行Spring Bean相关的实例化。
refresh(context);
}
注册钩子函数
@Override
public void registerShutdownHook() {
if (this.shutdownHook == null) {
this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) {
@Override
public void run() {
synchronized (startupShutdownMonitor) {
doClose();
}
}
};
Runtime.getRuntime().addShutdownHook(this.shutdownHook);
}
}
registerShutdownHook
方法是一个自定义方法,它用于注册一个JVM关闭钩子(shutdown hook)。这个方法首先检查shutdownHook
成员变量是否为null
,如果是null
,则创建一个新的线程并注册为JVM的关闭钩子。这个新线程在JVM关闭时将执行doClose()
方法。
refresh方法
刷新准备
prepareRefresh();
内部实现:
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}
// 初始化属性
initPropertySources();
// 校验设置的属性是否合法
getEnvironment().validateRequiredProperties();
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);
}
// 初始化一个集合属性,提供用来保存后面创建的事件,如果有事件发生会放入这个集合中
this.earlyApplicationEvents = new LinkedHashSet<>();
}
获取bean工厂
// 告诉子类刷新内部bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
内部实现:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 对创建的这个 beanFactory(DefaultListableBeanFactory类型)设置一个序列号
refreshBeanFactory();
// 获取beanFactory,将上一步设置好序列号的的beanFactory返回
return getBeanFactory();
}
bean工厂的预准备工作
prepareBeanFactory(beanFactory);
配置工厂的标准上下文(容器)特征,例如上下文的ClassLoader和后处理器 内部实现
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 设置 beanFactory 的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
if (!shouldIgnoreSpel) {
// 设置支持表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
// 为 beanFactory 增加了一个默认的 propertyEditor ,这个主要是对 bean 的属性等设置管理的一个工具
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 添加部分BeanPostProcessor【ApplicationContextAwareProcessor】
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware等
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(ApplicationStartup.class);
// 注册可以解析的自动装配;我们能直接在任何组件中自动注入
beanFactory.registeresolvableDependency(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.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 增加对 AspectJ 的支持
if (!IN_NATIVE_IMAGE && 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()));
}
// 环境信息ConfigurableEnvironment
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
// 系统属性,systemProperties【Map<String, Object>】
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
// 系统环境变量systemEnvironment【Map<String, Object>】
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}
bean工厂的后置处理
postProcessBeanFactory(beanFactory);
这里是一个空实现,留给子类重写。可以在 beanFactory 完成创建后做进一步设置。
对于 Servlet 而言,就是设置一些作用域之类的,例如 request、session 等。
内部实现
public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory, @Nullable ServletContext sc) {
beanFactory.registerScope("request", new RequestScope());
beanFactory.registerScope("session", new SessionScope());
if (sc != null) {
ServletContextScope appScope = new ServletContextScope(sc);
beanFactory.registerScope("application", appScope);
sc.setAttribute(ServletContextScope.class.getName(), appScope);
}
beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
if (jsfPresent) {
WebApplicationContextUtils.FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
}
}
调用后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
调用所有注册的BeanFactoryPostProcessor
实例,以便对BeanFactory
进行额外的配置或修改。
BeanFactoryPostProcessor
是Spring框架中的一个接口,它允许你在Spring的BeanFactory
标准初始化之后,但在任何bean创建之前,修改BeanFactory
的内容。这对于添加额外的bean定义、修改bean的属性或进行其他任何需要在bean实例化之前进行的操作非常有用。
在Spring容器启动过程中,invokeBeanFactoryPostProcessors
方法会遍历所有注册的BeanFactoryPostProcessor
,并调用它们的postProcessBeanFactory
方法。这样,这些处理器就可以对BeanFactory
进行必要的修改。
关键步骤:
- 获取所有的BeanFactoryPostProcessor:Spring容器会查找所有实现了
BeanFactoryPostProcessor
接口的bean,并将它们收集起来。 - 排序:如果
BeanFactoryPostProcessor
实现了Ordered
接口或者通过注解@Order
指定了顺序,那么它们会按照指定的顺序进行排序。 - 调用postProcessBeanFactory方法:对于每个
BeanFactoryPostProcessor
,都会调用其postProcessBeanFactory
方法,允许它们对BeanFactory
进行修改。 - 处理特殊的BeanFactoryPostProcessor:有些特殊的
BeanFactoryPostProcessor
(如ConfigurationClassPostProcessor
)可能需要在其他BeanFactoryPostProcessor
之后执行,因此会有额外的逻辑来处理这些特殊情况。
通过invokeBeanFactoryPostProcessors
方法,Spring框架提供了很大的灵活性,允许用户或第三方库在Spring容器初始化过程中插入自定义逻辑。这有助于实现复杂的配置需求,如条件bean创建、动态bean定义或修改现有bean的属性等。
注册拦截Bean创建的Bean处理器
registerBeanPostProcessors(beanFactory);
找到BeanPostPocessor的实现,排序后注册进容器内。
国际化、多语言配置
initMessageSource();
初始化事件广播器
initApplicationEventMulticaster();
当前有监听器就用监听器;没有的话,就新建一个
在特定上下文子类中初始化其他特殊bean
onRefresh();
由子类实现,Servlet 下主要表现为创建 web 容器。
检查监听器并注册
registerListeners();
转载自:https://juejin.cn/post/7352450333912498185