Spring源码:Bean创建(二)createBean方法 - Go语言中文社区

Spring源码:Bean创建(二)createBean方法


一、获取单例 getSingleton

创建单例bean的代码在getSingleton中实现:

	//省略了日志打印和异常捕获的代码
	public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		//单例模式下创建bena需要加锁同步
		synchronized (this.singletonObjects) {
			//如果bean已经创建,则直接返回就好
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,"...");
				}
				//这一步是将正在创建的bean记录在缓存中,以便对循环依赖进行检查
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				try {
					//创建单例
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				//省略异常捕获
				finally {
					//移除正在加载的bean记录,与beforeSingletonCreation相对应
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
					//将bean添加到缓存,并且移除加载过程中记录的各种辅助状态
					addSingleton(beanName, singletonObject);
				}
			}
			return singletonObject;
		}
	}

因为考虑到多线程获取bean的原因,单例bean的创建是全程加锁的,下面是方法的大致流程:

  1. 检查缓存中是否已经有bean的实例
  2. 如果还没有加载,则记录beanName为正在加载状态
  3. 通过传入的ObjectFactory实例化bean
  4. 与步骤2对应,移除正在加载的状态
  5. 添加结果到缓存,并且移除加载bean过程中的各种辅助状态
	protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.put(beanName, singletonObject);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}

二、ObjectFactory

从上面创建单例的代码可以看到,真正创建bean的功能委托给了ObjectFactory,通过它的getObject方法来创建,那么这个ObjectFactory是在哪里创建的?回顾上一节的doGetBean方法:

// Create bean instance.
if (mbd.isSingleton()) {
	sharedInstance = getSingleton(beanName, () -> {
		try {
			//调用createBean方法
			return createBean(beanName, mbd, args);
		}
		catch (BeansException ex) {
			// 创建失败会删除中间状态
			destroySingleton(beanName);
			throw ex;
		}
	});
	bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

再看一下其他scope的bean创建:

else {
	String scopeName = mbd.getScope();
	final Scope scope = this.scopes.get(scopeName);
	if (scope == null) {
		throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
	}
	try {
		Object scopedInstance = scope.get(beanName, () -> {
			beforePrototypeCreation(beanName);
			try {
                //调用createBean方法
				return createBean(beanName, mbd, args);
			}
			finally {
			afterPrototypeCreation(beanName);
			}
		});
		bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
	}
	//省略catch。。。
}

可以看到,不管是哪种类型的bean,都是通过createBean方法创建的。不一样的是,不同scope的bean在创建前后会有不一样的状态保存工作。

三、createBean方法

1、方法结构

在AbstractBeanFactory中,createBean的方法并未实现,而是将具体创建bean的工作留给了子类,是一个典型的模版方法:

在AbstractAutowireCapableBeanFactory 中实现了该方法:

	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
		RootBeanDefinition mbdToUse = mbd;

		// 确定并加载bean的class
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// 验证以及准备需要覆盖的方法
		mbdToUse.prepareMethodOverrides();

		try {
			// 给BeanPostProcessors 一个机会来返回代理对象来代替真正的实例,在这里实现创建代理对象功能
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		//catch...

		try {
			//创建bean
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			return beanInstance;
		}
		//catch
	}

上面代码对应步骤:

  1. 根据设置的class属性或者className来解析、加载class
  2. 对override属性进行标记和验证(bean XML配置中的lookup-method和replace-method属性)
  3. 应用初始化前的后处理器,如果处理器中返回了AOP的代理对象,则直接返回该单例对象,不需要继续创建
  4. 创建bean

2、初始化前的后处理器:InstantiationAwareBeanPostProcessor

createBean方法中调用了resolveBeforeInstantiation 方法做些前置处理,并且如果在这个方法中返回了bean的话(AOP代理对象或者自定义对象),就直接返回这个bean,不再继续后面的创建步骤,方法实现:

	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		//bean还未被解析
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					//应用实例化前的后处理器
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						//如果bean不为空,则应用实例化后的后处理器
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			//标记当前bean是否被解析过
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

a、实例化前的后处理器

	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		//遍历所有的后处理器
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				//应用其中类型为 InstantiationAwareBeanPostProcessor 的后处理器
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				//如果后处理器中创建了代理bean,则直接返回
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}

b、实例化后的后处理器

如果实例化前的后处理器创建了一个代理对象,才会继续应用实例化后的后处理器:

bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
	bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}

应用后处理器的方法与a中类似,只不过调用的是 postProcessBeforeInstantiation ,而后者调用的是 postProcessAfterInstantiation

	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {
		Object result = existingBean;
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
			Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
			//当其中一个后处理器返回null时,就会中断处理器的调用链,直接返回
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

四、doCreateBean

终于到了Spring创建bean的地方,下面是代码实现:

	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
		// 先从factoryBeanInstanceCache缓存中尝试获取
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		//如果缓存中不存在,则根据bean对应的策略创建新的实例,如:工厂方法、构造器自动注入、简单初始化
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// 应用MergedBeanDefinitionPostProcessor 后处理器,合并bean的定义信息
		// Autowire等注解信息就是在这一步完成预解析,并且将注解需要的信息放入缓存
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				//catch..
				mbd.postProcessed = true;
			}
		}

		// 是否需要提前曝光=单例&允许循环依赖&bean正在创建中
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			//为了避免循环依赖,在bean初始化完成前,就将创建bean实例的ObjectFactory放入工厂缓存(singletonFactories)
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// 对bean属性进行填充,注入bean中的属性,会递归初始化依赖的bean
		Object exposedObject = bean;
		try {
			populateBean(beanName, mbd, instanceWrapper);
			//调用初始化方法,比如init-method、注入Aware对象、应用后处理器
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		//catch 

		if (earlySingletonExposure) {
			//从提前曝光的bean缓存中查询bean,目的是验证是否有循环依赖存在
			//如果存在循环依赖,也就是说该bean已经被其他bean递归加载过,放入了提早曝光的bean缓存中
			Object earlySingletonReference = getSingleton(beanName, false);
			//只有检测到循环依赖的情况下,earlySingletonReference才不会为null
			if (earlySingletonReference != null) {
				//如果exposedObject没有在 initializeBean 初始化方法中改变,也就是没有被增强
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					//检测依赖
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					//因为bean创建后,其依赖的bean一定也是已经创建的
					//如果actualDependentBeans不为空,则表示依赖的bean并没有被创建完,即存在循环依赖
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException("...");
					}
				}
			}
		}

		// 根据scope注册bean
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		//catch。。。
		return exposedObject;
	}
  1. 如果是单例则首先清除缓存
  2. 实例化bean,并使用BeanWarpper包装
    1. 如果存在工厂方法,则使用工厂方法实例化
    2. 如果有多个构造函数,则根据传入的参数确定构造函数进行初始化
    3. 使用默认的构造函数初始化
  3. 应用MergedBeanDefinitionPostProcessor,Autowired注解就是在这样完成的解析工作
  4. 依赖处理。如果A和B存在循环依赖,那么Spring在创建B的时候,需要自动注入A时,并不会直接创建再次创建A,而是通过放入缓存中A的ObjectFactory来创建实例,这样就解决了循环依赖的问题
  5. 属性填充。所有需要的属性都在这一步注入到bean
  6. 循环依赖检查
  7. 注册DisposableBean。如果配置了destroy-method,这里需要注册,以便在销毁时调用
  8. 完成创建并返回

 

 

 

 

 

 

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/finalcola/article/details/81449140
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-07 15:16:11
  • 阅读 ( 729 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢