likes
comments
collection
share

Spring Boot 源码分析(四)

作者站长头像
站长
· 阅读数 6

应用上下文

刷新容器

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进行必要的修改。

关键步骤

  1. 获取所有的BeanFactoryPostProcessor:Spring容器会查找所有实现了BeanFactoryPostProcessor接口的bean,并将它们收集起来。
  2. 排序:如果BeanFactoryPostProcessor实现了Ordered接口或者通过注解@Order指定了顺序,那么它们会按照指定的顺序进行排序。
  3. 调用postProcessBeanFactory方法:对于每个BeanFactoryPostProcessor,都会调用其postProcessBeanFactory方法,允许它们对BeanFactory进行修改。
  4. 处理特殊的BeanFactoryPostProcessor:有些特殊的BeanFactoryPostProcessor(如ConfigurationClassPostProcessor)可能需要在其他BeanFactoryPostProcessor之后执行,因此会有额外的逻辑来处理这些特殊情况。

通过invokeBeanFactoryPostProcessors方法,Spring框架提供了很大的灵活性,允许用户或第三方库在Spring容器初始化过程中插入自定义逻辑。这有助于实现复杂的配置需求,如条件bean创建、动态bean定义或修改现有bean的属性等。

注册拦截Bean创建的Bean处理器

registerBeanPostProcessors(beanFactory);

找到BeanPostPocessor的实现,排序后注册进容器内。

国际化、多语言配置

initMessageSource();

初始化事件广播器

initApplicationEventMulticaster();

当前有监听器就用监听器;没有的话,就新建一个

在特定上下文子类中初始化其他特殊bean

onRefresh();

由子类实现,Servlet 下主要表现为创建 web 容器。

检查监听器并注册

registerListeners();