Spring源码(十六)bean实例化过程CreateBeanInstance方法

Spring源码(十六)bean实例化过程CreateBeanInstance方法

实例化过程以及创建对象的方式

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		// 这个beanWrapper是用来持有创建出来的bean对象的
		BeanWrapper instanceWrapper = null;
		// 获取factoryBean实例缓存
		if (mbd.isSingleton()) {
			// 如果是单例对象,从factorybean实例缓存中移除当前bean定义信息
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		// 没有就创建实例
		if (instanceWrapper == null) {
			// 根据执行bean使用对应的策略创建新的实例,如,工厂方法,构造函数主动注入、简单初始化
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		// 从包装类中获取原始bean
		Object bean = instanceWrapper.getWrappedInstance();
		// 获取具体的bean对象的Class属性
		Class<?> beanType = instanceWrapper.getWrappedClass();
		// 如果不等于NullBean类型,那么修改目标类型
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// Allow post-processors to modify the merged bean definition.
		// 允许beanPostProcessor去修改合并的beanDefinition
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					// MergedBeanDefinitionPostProcessor后置处理器修改合并bean的定义
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		// 判断当前bean是否需要提前曝光:单例&允许循环依赖&当前bean正在创建中,检测循环依赖
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			// 为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

			//只保留二级缓存,不向三级缓存中存放对象
//			earlySingletonObjects.put(beanName,bean);
//			registeredSingletons.add(beanName);

		}

		// Initialize the bean instance.
		// 初始化bean实例
		Object exposedObject = bean;
		try {
			// 对bean的属性进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始化依赖的bean
			populateBean(beanName, mbd, instanceWrapper);
			// 执行初始化逻辑
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

		if (earlySingletonExposure) {
			// 从缓存中获取具体的对象
			Object earlySingletonReference = getSingleton(beanName, false);
			// earlySingletonReference只有在检测到有循环依赖的情况下才会不为空
			if (earlySingletonReference != null) {
				// 如果exposedObject没有在初始化方法中被改变,也就是没有被增强
				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) {
						// 返回false说明依赖还没实例化好
						if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
							actualDependentBeans.add(dependentBean);
						}
					}
					// 因为bean创建后所依赖的bean一定是已经创建的
					// actualDependentBeans不为空则表示当前bean创建后其依赖的bean却没有全部创建完,也就是说存在循环依赖
					if (!actualDependentBeans.isEmpty()) {
						throw new BeanCurrentlyInCreationException(beanName,
								"Bean with name '" + beanName + "' has been injected into other beans [" +
								StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
								"] in its raw version as part of a circular reference, but has eventually been " +
								"wrapped. This means that said other beans do not use the final version of the " +
								"bean. This is often the result of over-eager type matching - consider using " +
								"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
			// 注册bean对象,方便后续在容器销毁的时候销毁对象
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

提前写一下,这里粗分为几个步骤,首先调用createBeanInstance实例化,然后applyMergedBeanDefinitionPostProcessors这里是AOP的核心处理方法,继续会将当前对象加入到三级缓存,连同lambda表达式,为了解决循环依赖问题,继续到了populateBean方法,对bean的属性填充。继续到了initializeBean方法,初始化Bean对象。然后调用registerDisposableBeanIfNecessary销毁对象。

先看下createBeanInstance方法。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// Make sure bean class is actually resolved at this point.
		// 确认需要创建的bean实例的类可以实例化
		Class<?> beanClass = resolveBeanClass(mbd, beanName);

		// 确保class不为空,并且访问权限是public
		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}

		// 判断当前beanDefinition中是否包含实例供应器,此处相当于一个回调方法,利用回调方法来创建bean
		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}

		// 如果工厂方法不为空则使用工厂方法初始化策略
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// 一个类可能有多个构造器,所以Spring得根据参数个数、类型确定需要调用的构造器
		// 在使用构造器创建实例后,Spring会将解析过后确定下来的构造器或工厂方法保存在缓存中,避免再次创建相同bean时再次解析

		// Shortcut when re-creating the same bean...
		// 标记下,防止重复创建同一个bean
		boolean resolved = false;
		// 是否需要自动装配
		boolean autowireNecessary = false;
		// 如果没有参数
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				// 因为一个类可能由多个构造函数,所以需要根据配置文件中配置的参数或传入的参数来确定最终调用的构造函数。
				// 因为判断过程会比较,所以spring会将解析、确定好的构造函数缓存到BeanDefinition中的resolvedConstructorOrFactoryMethod字段中。
				// 在下次创建相同时直接从RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod缓存的值获取,避免再次解析
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		// 有构造参数的或者工厂方法
		if (resolved) {
			// 构造器有参数
			if (autowireNecessary) {
				// 构造函数自动注入
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				// 使用默认构造函数构造
				return instantiateBean(beanName, mbd);
			}
		}

		// Candidate constructors for autowiring?
		// 从bean后置处理器中为自动装配寻找构造方法, 有且仅有一个有参构造或者有且仅有@Autowired注解构造
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		// 以下情况符合其一即可进入
		// 1、存在可选构造方法
		// 2、自动装配模型为构造函数自动装配
		// 3、给BeanDefinition中设置了构造参数值
		// 4、有参与构造函数参数列表的参数
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// Preferred constructors for default construction?
		// 找出最合适的默认构造方法
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
			// 构造函数自动注入
			return autowireConstructor(beanName, mbd, ctors, null);
		}

		// No special handling: simply use no-arg constructor.
		// 使用默认无参构造函数创建对象,如果没有无参构造且存在多个有参构造且没有@AutoWired注解构造,会报错
		return instantiateBean(beanName, mbd);
	}

这个方法首先获取Class对象,继续往下,if用来判断访问权限是否是public,否则报错。

继续往下,getInstanceSupplier方法,实际上,supplier是一个函数式接口,所以会调用get方法,就是到实际上传进来的方法。
这里用getInstanceSupplier时,发现instanceSupplier为空,那么如何让其有值呢?
因为这个方法是在bd中的(有getInstanceSupplier就会有SetInstanceSupplier,从这点入手找到该类为abstractBeanDefinition),如果想修改bd,只能在BFPP里面做相关实现了。(supplier,用的genicBeanDefinition里的setInstanceSupplier),

所以这里也可以用supplier创建对象,不会走反射流程。
在这里插入图片描述
继续往下,有个factoryMethod创建对象的方式。instantiateUsingFactoryMethod。这种也可以提前实力化对象。

上面总结一下,创建对象的方式。

在这里插入图片描述

继续往下就是构造器的选用以及实例化过程了。
resolvedConstructorOrFactoryMethod这个可以认为缓存,如果需要多次取构造器,那么可以不用再次通过选择构造器操作,在这里可以直接拿到构造器。

用原型测试。
进入到instantiateBean,再到instantiate方法。这个时候构造函数还没有确定。但是再instantiate创建了默认的构造器,并设置到resolvedConstructorOrFactoryMethod值。第二次用getBean访问时,会访问到。这个参数起到了缓存的作用。有参的就到了constructorResolver方法中了,resolvedConstructorOrFactoryMethod进行缓存了。

然后看到determineConstructorsFromBeanPostProcessors方法。这个方法从bean后置处理器中为自动装配寻找构造方法, 有且仅有一个有参构造或者有且仅有@Autowired注解构造才能有效果。为什么我们可以从BeanPostProcessor中可以获得构造器?因为有个smartInstationAwareBeanPostProcessor接口,这个接口有个方法determineCandidateConstructors,有个方法实现AutowiredAnnotationBeanPostProcessor,这个方法主要筛选了一些构造方法。排除了一些错误使用@autowired方法的情况。

继续往下,到了autowireConstructor方法。此方法是再ConstructorResolver下的autowireConstructor。

以下情况符合其一即可进入
1、存在可选构造方法
2、自动装配模型为构造函数自动装配
3、给BeanDefinition中设置了构造参数值
4、有参与构造函数参数列表的参数

这个方法也会将选择的构造器放入缓存storeCache中,为了下次使用可以不用再找了。这个方法比较复杂,大概逻辑是将构造器的参数进行排序,然后选择参数的数量,如果不满足,则不去找小于现在参数数量的构造器。如果进入此方法,那么实例化instantiate在此方法中完成。

接下来到instantiateBean,实例化的过程。

获取实例化策略,再instantiate,实例化策略默认用的cglib这个类。这里有一个接口,instantiationStrategy,有三个方法同名的。无参构造,指定构造器,指定factorymethod实例化。而它有一个实现子类,为simpleInstantiationStrategy,里面有具体instance方法的实现。

而cglibsubclassingInstantiationStrategy继承了simpleInstantiationStrategy,
在这里插入图片描述
这里对这两个方法做了扩展操作。实例化这里多了两种实现方式,cglib是否带构造器。一共5种,simple里面三种,无参,有参,factortmethod,而cglib多了2种,通过动态代理方式,一个直接用了具体构造器,一个构造器为空。

实例化策略:包含simple实例化策略((普通对象)无参构造实例化、有参构造实例化、factorymethod工厂方法实例化),cglib实例化策略(动态代理对象(无参构造(构造器为空)、有参构造(构造器不为空)))
在这里插入图片描述

这就是实例化

下面进行初始化了。返回到调用createBeanInstance方法,也就是doCreateBean方法。

继续往下
在这里插入图片描述

这里是为了解决@preconstructor,允许用beanPostProceesor修改BD。
(实例化好了,但是不知道初始化方法与销毁方法是什么,对于注解来说,需要找到相关类。比如加init-method与destry-method,但是xml文件可以,如果用了注解,则会进入,这里使用了注解的方式@postConstruct与@predestory这样的注解,进行识别)
mergedBeanDefinitionPostProcessor,这里的子类有很多annotation,
在这里插入图片描述
先看common,super的父类是initDestoryAnnotationBeanPostProcessor,有个方法findLifeCycleMetadata,通过buildLifecycleMetadata方法构建生命周期,一个是初始化方法一个是销毁方法,再写回BD中。

实际上这里并没有执行,只是加入了集合,最后在BPP的invokeinitMethod方法这里执行。

上面仅仅是common的super的,还有它本身的代码逻辑
在这里插入图片描述
这是找@resource注解。然后还是调用了findResourceMetadata方法进行处理。

总结

三个自定义创建对象的方式。

如何实例化策略的,选择构造器。

在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值