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