【源码】Spring —— BeanFactory 解读 2 AbstractBeanFactory

97 阅读5分钟

【源码】Spring —— BeanFactory 解读 2 AbstractBeanFactory

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

前言

上一章节介绍了 BeanFactory 相关接口,本章节解读顶层抽象实现类 AbstractBeanFactory

版本

Spring 5.3.x

AbstractBeanFactory

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory
  • AbstractBeanFactory 实现了 ConfigurableBeanFactory 接口,是顶层抽象实现类,实现了最基本的方法
  • 同时,它也是一个 FactoryBeanRegistrySupport,即单例注册中心,负责管理所有 单例

BeanFactory 接口方法实现

	@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

	@Override
	public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
		return doGetBean(name, requiredType, null, false);
	}

	@Override
	public Object getBean(String name, Object... args) throws BeansException {
		return doGetBean(name, null, args, false);
	}

	public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
			throws BeansException {
		return doGetBean(name, requiredType, args, false);
	}

基于 name 获取 bean实例getBean 方法收口都到 doGetBean

doGetBean

接下来是 doGetBean 的代码解读,这里的篇幅可能会有点长,对一些无关的代码做了省略,可结合注释阅读,代码后也会给出对应的方法概括

	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {

		/**
		 * 对于 &前缀的 beanName 进行转换(及去掉 &)
		 * 同时别名也会转换为原名
		 */
		String beanName = transformedBeanName(name);
		Object bean;

		// DefaultSingletonBeanRegistry#getSingleton
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			// 获取 单例实例
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		// 获取不到:没有创建,或者压根就不是单例等
		else {
			// 正在创建中则抛出异常
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// 试图从 父工厂 获取
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// 略
			}

			if (!typeCheckOnly) {
				// 标记当前 bean 为 created
				markBeanAsCreated(beanName);
			}

			try {
				// RootBeanDefinition 获取
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

				// 检查 RootBeanDefinition 属性:当前 bean 不能是 Abstract
				checkMergedBeanDefinition(mbd, beanName, args);

				// 先把当前 bean 依赖(depends on)的 bean 都创建出来
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						// 禁止递归依赖:A 依赖 B,B 又依赖 A
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException("...");
						}
						// 注册依赖关系
						registerDependentBean(dep, beanName);
						try {
							// 现获取依赖的 bean 实例
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							// ...
						}
					}
				}

				/**
				 * 如果是单例
				 * 则创建对应的 单例工厂 ,并由 DefaultSingletonBeanRegistry#getSingleton 来负责创建单例
				 * 而实际上 singletonFactory.getObject() 方法是委托给了
				 * 		createBean(beanName, mbd, args) 交由子类实现
				 */
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// 创建失败则销毁
							destroySingleton(beanName);
							throw ex;
						}
					});

					// 单例实例获取
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				/**
				 * 如果是原型
				 * 则每次获取一个新的实例
				 */
				else if (mbd.isPrototype()) {
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}
				/**
				 * 如果是其他作用域
				 * 则如同 单例 一样创建对应的 单例工厂,委托给 Scope 获取实例
				 * 而 单例工厂 的 getObject 方法委托给 createBean(beanName, mbd, args) 交由子类实现
				 */
				else {
					String scopeName = mbd.getScope();
					
					// ...
					
					try {
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						// ...
					}
				}
			}
			catch (BeansException ex) {
				// ...
			}
		}

		// 转换成需要的类型
		if (requiredType != null && !requiredType.isInstance(bean)) {
			try {
				T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
				if (convertedBean == null) {
					throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
				}
				return convertedBean;
			}
			catch (TypeMismatchException ex) {
				// ...
			}
		}

		// 返回
		return (T) bean;
	}

此处大致总结下方法逻辑,可结合具体注释阅读

  • 先调用 DefaultSingletonBeanRegistry#getSingleton 方法获取,如果获取到了,处理(因为可能是个 FactoryBean)并返回
  • 如果没有获取到,则可能没有创建或者不是 单例,试图从 父BeanFactory 获取。如果也没有则获取对应的 RootBeanDefinition ,根据不同的 Scope 创建相应的 bean
  • 创建对应的实例前,需要先创建 依赖 的所有 bean
  • 对于 单例,我们创建对应的 ObjectFactory,委托给 DefaultSingletonBeanRegistry 创建,而 ObjectFactory#getObject 方法又是委托给子类的 createBean 方法实现,创建完成后加入 单例池
  • 对于 原型,直接调用 createBean 方法创建新的实例
  • 对于其他作用域,类似 单例 的创建,将对应的 ObjectFactory 委托给对应的 Scope 创建,而 ObjectFactory#getObject 方法又是委托给子类的 createBean 方法实现
  • 实例创建完成后基于 TypeConverter 组件转换成所需类型
  • 最终方法都收口在 createBean,而这就是本类把暴露出的核心抽象方法,交由子类实现,调用链 getBean -> doGetBean -> createBean
这里的 Scope 比如在 Web容器 中常见的 REQUEST SESSION,结合上下文获取
基本实现了 BeanFactory 接口定义的所有方法

HierarchicalBeanFactory 接口方法实现

	@Override
	@Nullable
	public BeanFactory getParentBeanFactory() {
		return this.parentBeanFactory;
	}

	@Override
	// 存在指定单例或指定BeanDefinition
	// 同时如果是 & 前缀,必须是个 FactoryBean
	public boolean containsLocalBean(String name) {
		String beanName = transformedBeanName(name);
		return ((containsSingleton(beanName) || containsBeanDefinition(beanName)) &&
				(!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(beanName)));
	}

AbstractBeanFactory 实现了 HierarchicalBeanFactory 定义的两个方法

ConfigurableBeanFactory 接口方法实现

ConfigurableBeanFactory 接口方法的实现多是普通的 getter & setter 实现,其中:

BeanPostProcessor 相关

	@Override
	public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {

		// 缓存清除
		this.beanPostProcessors.remove(beanPostProcessor);
		
		// 设置 hasInstantiationAwareBeanPostProcessors 和 hasDestructionAwareBeanPostProcessors 标识位
		if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
			this.hasInstantiationAwareBeanPostProcessors = true;
		}
		if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
			this.hasDestructionAwareBeanPostProcessors = true;
		}
	
		// 缓存
		this.beanPostProcessors.add(beanPostProcessor);
	}

	@Override
	public int getBeanPostProcessorCount() {
		return this.beanPostProcessors.size();
	}

	public List<BeanPostProcessor> getBeanPostProcessors() {
		return this.beanPostProcessors;
	}

BeanPostProcessor 的添加,会同时更新 hasInstantiationAwareBeanPostProcessorshasDestructionAwareBeanPostProcessors 标识

对 ConfigurableBeanFactory 的很多方法提供了实现,不一一了解

抽象方法

AbstractBeanFactory 主要定义了三个核心的 抽象方法,交由子类实现

containsBeanDefinition

protected abstract boolean containsBeanDefinition(String beanName);
  • 根据给定 beanName 判断当前容器是否存在对应的 BeanDefinition
  • 该方法在 ListableBeanFactory 也有定义(AbstractBeanFactory 未实现 ListableBeanFactory 接口)

getBeanDefinition

protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;
  • 返回给定 beanName 对应的 BeanDefinition

createBean

protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException;
  • 根据之前的了解,整个 bean 实例的方法链路总结为:getBean -> doGetBean -> createBean
  • 具体基于 BeanDefinition 创建实例的操作,由子类实现

总结

作为顶层抽象实现,AbstractBeanFactory 实现了 BeanFactory HierarchicalBeanFactory ConfigurableBeanFactory 定义的大多数方法,同时将核心方法抽象出来交由子类拓展与实现