Spring IOC(二): refresh 分析 prepare过程

本文继续跟着上一篇文章走,开始分析 AbstractApplicationrefresh 方法。

本文主要围绕以下几个方面进行:

加锁

AbstractApplication 中,定义了 Object 类型的 变量 startupShutdownMonitor 作为锁。当执行 refresh 和 destroy 方法则会进行加锁禁止并发操作。

synchronized (this.startupShutdownMonitor) {
   ... 
}

prepareRefresh

该方法,主要是为refresh 方法执行 准备操作。

	protected void prepareRefresh() {
		// 设置启动日期,closed 和 active 状态
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);
		// log 打日志
		if (logger.isDebugEnabled()) {
			if (logger.isTraceEnabled()) {
				logger.trace("Refreshing " + this);
			}
			else {
				logger.debug("Refreshing " + getDisplayName());
			}
		}
		// 初始化 一些环境变量信息,由子类实现。
		initPropertySources();
		// 验证所有变量的合法性
		getEnvironment().validateRequiredProperties();
		// 存储 pre-refresh 类型的 ApplicationListeners
		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);
		}
		// 初始化 early ApplicationEvents 类型的事件,允许 multicaster 可用时立刻触发。
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

以上几步主要是初始化 资源,例如 earlyApplicationListenersapplicationListenersearlyApplicationEvents
另一方面,也会使用 initPropertySources去加载子类所需要的一些 属性。
validateRequiredProperties 则是对属性进行验证。
例如,如果项目项目里面使用了 某一个环境变量,而 对应机器或者 在 initPropertySources 加载资源未加载进去,则可以在 validateRequiredProperties 验证不通过进行告警。

obtainFreshBeanFactory

在这里面主要是让子类去刷新(refresh) beanFactory。

obtainFreshBeanFactory:

	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();
		return getBeanFactory();
	}

refreshBeanFactory 是 protected 的空方法,主要看子类如何实现。

本文使用 是 AnnotationConfigApplicationContext
在这里插入图片描述

在 当前类 AnnotationConfigApplicationContext 中,并没有 实现 refreshBeanFactory,而在 其父类 GenericApplication 中有实现该方法,并在 在GenericApplication 中会对 final 成员变量 beanFactory 进行初始化。默认构造为 DefaultListableBeanFactory
GenericApplicationContextrefreshBeanFactory

	@Override
	protected final void refreshBeanFactory() throws IllegalStateException {
		if (!this.refreshed.compareAndSet(false, true)) {
			throw new IllegalStateException(
					"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
		}
		this.beanFactory.setSerializationId(getId());
	}

里面判断了 beanFactory 初始化状态,以及设置 了 beanFactory 的序列化id。
在这里插入图片描述

prepareBeanFactory

准备完环境,初始化了BeanFactory,那么到这里就开始要为使用BeanFactory做准备了。

	protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// Tell the internal bean factory to use the context's class loader etc.
		beanFactory.setBeanClassLoader(getClassLoader());
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		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 interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		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.
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		if (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.
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}

上文准备过程,包括添加classLoader,忽略了一些DependencyInterface(这些不需要bean初始化),还添加了两个BeanPostProcessor

  1. ApplicationContextAwareProcessor: 用于在初始化bean时候,自动填入一些属性。
  2. ApplicationListenerDetector: 添加ApplicationListeners 所需要的支持。

后面则根据需要提前注册了一些bean。

觉得博主写的有用,不妨关注博主公众号: 六点A君。
哈哈哈,一起研究Spring:
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章