欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring Bean的实例化之属性注入源码剖析过程

程序员文章站 2022-07-08 20:53:34
前言来讨论创建bean过程中的属性注入,在spring的ioc容器启动过程中,会把定义的bean封装成beandefinition注册到一个concurrenthashmap中,bean注册完成后,就...

前言

来讨论创建bean过程中的属性注入,在spring的ioc容器启动过程中,会把定义的bean封装成beandefinition注册到一个concurrenthashmap中,bean注册完成后,就会对单利的且lazy-init=false 的bean进行实例化。创建bean的代码在 abstractautowirecapablebeanfactory#docreatebean 中,当bean创建成功之后,会调用abstractautowirecapablebeanfactory#populatebean 方法进行属性注入。本篇文章主要就是分析该方法是如何实现bean的属性注入的。

这里先上一个属性注入的流程图,待会儿可以根据这个图来看代码

Spring Bean的实例化之属性注入源码剖析过程

属性注入:abstractautowirecapablebeanfactory#populatebean

abstractautowirecapablebeanfactory#populatebean 方法的主要功能就是属性填充,源码如下

//使用 bean 定义中的属性值填充给定 beanwrapper 中的 bean 实例。
	@suppresswarnings("deprecation")  // for postprocesspropertyvalues
	protected void populatebean(string beanname, rootbeandefinition mbd, @nullable beanwrapper bw) {
		if (bw == null) {
			//判断是否有property属性
			if (mbd.haspropertyvalues()) {
				throw new beancreationexception(
						mbd.getresourcedescription(), beanname, "cannot apply property values to null instance");
			}
			else {
				//没有任何属性可以填充
				// skip property population phase for null instance.
				return;
			}
		}

		// give any instantiationawarebeanpostprocessors the opportunity to modify the
		// state of the bean before properties are set. this can be used, for example,
		// to support styles of field injection.
		//让 instantiationawarebeanpostprocessors 也在属性注入之前改变bean的状态
		if (!mbd.issynthetic() && hasinstantiationawarebeanpostprocessors()) {
			for (beanpostprocessor bp : getbeanpostprocessors()) {
				if (bp instanceof instantiationawarebeanpostprocessor) {
					instantiationawarebeanpostprocessor ibp = (instantiationawarebeanpostprocessor) bp;
					if (!ibp.postprocessafterinstantiation(bw.getwrappedinstance(), beanname)) {
						return;
					}
				}
			}
		}
		//从 rootbeandefinition 获取所有的propertyvalues
		propertyvalues pvs = (mbd.haspropertyvalues() ? mbd.getpropertyvalues() : null);

		int resolvedautowiremode = mbd.getresolvedautowiremode();
		//根据名字获取根据type注入
		if (resolvedautowiremode == autowire_by_name || resolvedautowiremode == autowire_by_type) {
			mutablepropertyvalues newpvs = new mutablepropertyvalues(pvs);
			// add property values based on autowire by name if applicable.
			//如果适用,根据名称添加基于自动装配的属性值。
			if (resolvedautowiremode == autowire_by_name) {
				autowirebyname(beanname, mbd, bw, newpvs);
			}
			// add property values based on autowire by type if applicable.
			//如果适用,根据类型添加基于自动装配的属性值
			if (resolvedautowiremode == autowire_by_type) {
				autowirebytype(beanname, mbd, bw, newpvs);
			}
			pvs = newpvs;
		}
		//后置处理器是否已经注册,初始化好了
		boolean hasinstawarebpps = hasinstantiationawarebeanpostprocessors();
		//是否要检查依赖,默认false
		boolean needsdepcheck = (mbd.getdependencycheck() != abstractbeandefinition.dependency_check_none);

		propertydescriptor[] filteredpds = null;
		if (hasinstawarebpps) {
			if (pvs == null) {
				pvs = mbd.getpropertyvalues();
			}
			//获取后置处理器
			for (beanpostprocessor bp : getbeanpostprocessors()) {
				//如果是bean实例化后置处理器
				if (bp instanceof instantiationawarebeanpostprocessor) {
					instantiationawarebeanpostprocessor ibp = (instantiationawarebeanpostprocessor) bp;
					//
					propertyvalues pvstouse = ibp.postprocessproperties(pvs, bw.getwrappedinstance(), beanname);
					if (pvstouse == null) {
						if (filteredpds == null) {
							filteredpds = filterpropertydescriptorsfordependencycheck(bw, mbd.allowcaching);
						}
						//对需要依赖检查的属性进行后置处理
						pvstouse = ibp.postprocesspropertyvalues(pvs, filteredpds, bw.getwrappedinstance(), beanname);
						if (pvstouse == null) {
							return;
						}
					}
					pvs = pvstouse;
				}
			}
		}
		if (needsdepcheck) {
			if (filteredpds == null) {
				filteredpds = filterpropertydescriptorsfordependencycheck(bw, mbd.allowcaching);
			}
			checkdependencies(beanname, mbd, filteredpds, pvs);
		}

		if (pvs != null) {
			//依赖注入入口,讲属性应用到bean中
			applypropertyvalues(beanname, mbd, bw, pvs);
		}
	}

方法中的重要代码

  • autowirebyname : 根据属性名进行注入
  • autowirebytype:根据类型注入bean
  • instantiationawarebeanpostprocessor.postprocesspropertyvalues :该方法是在工厂将给定的属性值应用于给定的 bean 之前对给定的属性值进行处理,比如:requiredannotationbeanpostprocessor类中对属性的验证。
  • applypropertyvalues:属性的填充

autowirebyname是根据名字注入,源码如下

protected void autowirebyname(
			string beanname, abstractbeandefinition mbd, beanwrapper bw, mutablepropertyvalues pvs) {
		//寻找beanwrapper中需要依赖的属性
		string[] propertynames = unsatisfiednonsimpleproperties(mbd, bw);
		for (string propertyname : propertynames) {
			if (containsbean(propertyname)) {
				//递归实例化的bean
				object bean = getbean(propertyname);
				pvs.add(propertyname, bean);
				//注册依赖的bean,加入 dependentbeanmap 中
				registerdependentbean(propertyname, beanname);
				if (logger.istraceenabled()) {
					logger.trace("added autowiring by name from bean name '" + beanname +
							"' via property '" + propertyname + "' to bean named '" + propertyname + "'");
				}
			}
			else {
				if (logger.istraceenabled()) {
					logger.trace("not autowiring property '" + propertyname + "' of bean '" + beanname +
							"' by name: no matching bean found");
				}
			}
		}
	}

这个方法很简单,就是先找到依赖的bean,递归初始化,然后加入 pvs中

//定义“按类型自动装配”(按类型的 bean 属性)行为的抽象方法
	protected void autowirebytype(
			string beanname, abstractbeandefinition mbd, beanwrapper bw, mutablepropertyvalues pvs) {
		//类型转换器
		typeconverter converter = getcustomtypeconverter();
		if (converter == null) {
			converter = bw;
		}

		set<string> autowiredbeannames = new linkedhashset<>(4);
		//找到需要注入的属性
		string[] propertynames = unsatisfiednonsimpleproperties(mbd, bw);
		for (string propertyname : propertynames) {
			try {
				//属性描述
				propertydescriptor pd = bw.getpropertydescriptor(propertyname);
				// don't try autowiring by type for type object: never makes sense,
				// even if it technically is a unsatisfied, non-simple property.
				if (object.class != pd.getpropertytype()) {
					//获取对象的set方法
					methodparameter methodparam = beanutils.getwritemethodparameter(pd);
					// do not allow eager init for type matching in case of a prioritized post-processor.

					boolean eager = !(bw.getwrappedinstance() instanceof priorityordered);
					//依赖描述
					dependencydescriptor desc = new autowirebytypedependencydescriptor(methodparam, eager);
					//【重要】得到依赖的属性的值,存储到 autowiredbeannames 集合中
					//提供了对集合如:@autowired private list<a> as; 支持,根据类型走到所有的bean注入其中
					object autowiredargument = resolvedependency(desc, beanname, autowiredbeannames, converter);
					if (autowiredargument != null) {
						//添加到pvs
						pvs.add(propertyname, autowiredargument);
					}
					for (string autowiredbeanname : autowiredbeannames) {
						//注入依赖的bean
						registerdependentbean(autowiredbeanname, beanname);
						if (logger.istraceenabled()) {
							logger.trace("autowiring by type from bean name '" + beanname + "' via property '" +
									propertyname + "' to bean named '" + autowiredbeanname + "'");
						}
					}
					//清理掉依赖
					autowiredbeannames.clear();
				}
			}
			catch (beansexception ex) {
				throw new unsatisfieddependencyexception(mbd.getresourcedescription(), beanname, propertyname, ex);
			}
		}
	}

看到这,我们大概清楚了,其实在populatebean 方法中会先从rootbeandefinition 中获取 bean的属性(propertyvalues),同时也会根据rootbeandefinition的autowiremode自动注入模式来根据name或者type寻主bean的依赖的属性。

根据类型注入和根据名字注入都是先从beanwrapper 中找到bean的依赖的属性,然后根据属性类型找到匹配的bean,实现依赖注入。还提供了对集合如:@autowired private list<a> as; 集合注入的支持。

属性寻找好之后都会封装成 propertyvalues,然后传给applypropertyvalues应用到bean身上。

abstractautowirecapablebeanfactory#applypropertyvalues

我们可以认为前面的代码是在为当前bean寻找依赖的的属性,封装到 propertyvalues中,在applypropertyvalues中才是把属性应用到当前bean。

//处理对象之间的引用,使用深拷贝
	protected void applypropertyvalues(string beanname, beandefinition mbd, beanwrapper bw, propertyvalues pvs) {
		if (pvs.isempty()) {
			return;
		}

		if (system.getsecuritymanager() != null && bw instanceof beanwrapperimpl) {
			((beanwrapperimpl) bw).setsecuritycontext(getaccesscontrolcontext());
		}

		mutablepropertyvalues mpvs = null;
		list<propertyvalue> original;

		if (pvs instanceof mutablepropertyvalues) {
			mpvs = (mutablepropertyvalues) pvs;
			//判断mpvs中的值是否已经转成了对应的类型,已经转了就可以直接设置值到 beanwrapper了
			if (mpvs.isconverted()) {
				// shortcut: use the pre-converted values as-is.
				try {
					//为实例化对象设置属性
					bw.setpropertyvalues(mpvs);
					return;
				}
				catch (beansexception ex) {
					throw new beancreationexception(
							mbd.getresourcedescription(), beanname, "error setting property values", ex);
				}
			}
			//获取属性值的原始类型
			original = mpvs.getpropertyvaluelist();
		}
		else {
			//如果类型不是mutablepropertyvalues , 就使用原生属性获取方法
			original = arrays.aslist(pvs.getpropertyvalues());
		}
		//获取用户自定义的型转换器
		typeconverter converter = getcustomtypeconverter();
		if (converter == null) {
			converter = bw;
		}
		//解析器:用于 bean 工厂实现的 helper 类,将 bean 定义对象中包含的值,解析为应用于目标 bean 实例的实际值。
		beandefinitionvalueresolver valueresolver = new beandefinitionvalueresolver(this, beanname, mbd, converter);

		// create a deep copy, resolving any references for values.
		//存放类型转换过的属性,把bean的属性解析值新建拷贝,把拷贝的数据注入到对象
		list<propertyvalue> deepcopy = new arraylist<>(original.size());
		boolean resolvenecessary = false;
		//类型转换,把属性转换为对应的类型
		for (propertyvalue pv : original) {
			if (pv.isconverted()) {
			//属性值不需要转
				deepcopy.add(pv);
			}
			else {
				//属性名
				string propertyname = pv.getname();
				//原始属性值,它的类型是一个 如: runtimebeanreference<otherbean> 引用类型
				object originalvalue = pv.getvalue();
				//转换属性值,将引用转换为 ioc 容器中实例化对象引用  otherbean
				object resolvedvalue = valueresolver.resolvevalueifnecessary(pv, originalvalue);
				object convertedvalue = resolvedvalue;
				
				boolean convertible = bw.iswritableproperty(propertyname) &&
						!propertyaccessorutils.isnestedorindexedproperty(propertyname);
				if (convertible) {
					//使用用户自定义的转换器转换
					convertedvalue = convertforproperty(resolvedvalue, propertyname, bw, converter);
				}
				// possibly store converted value in merged bean definition,
				// in order to avoid re-conversion for every created bean instance.
				if (resolvedvalue == originalvalue) {
					if (convertible) {
						//设置转换之后的值到pv ,把依赖的bean设置给propertyvalue
						pv.setconvertedvalue(convertedvalue);
					}
					deepcopy.add(pv);
				}
				else if (convertible && originalvalue instanceof typedstringvalue &&
						!((typedstringvalue) originalvalue).isdynamic() &&
						!(convertedvalue instanceof collection || objectutils.isarray(convertedvalue))) {
					pv.setconvertedvalue(convertedvalue);
					deepcopy.add(pv);
				}
				else {
					resolvenecessary = true;
					//转换好的依赖的属性最终放到一个arraylist中
					deepcopy.add(new propertyvalue(pv, convertedvalue));
				}
			}
		}
		if (mpvs != null && !resolvenecessary) {
			mpvs.setconverted();
		}

		// set our (possibly massaged) deep copy.
		try {
			//把解析好的属性 设置到 beanwrapper 中
			bw.setpropertyvalues(new mutablepropertyvalues(deepcopy));
		}
		catch (beansexception ex) {
			throw new beancreationexception(
					mbd.getresourcedescription(), beanname, "error setting property values", ex);
		}
	}

这里主要进行属性转换,然后应用到bean身上,这里的属性转换比如: 在beandefinition中属性可能是用字符串类型来描述的,需要把属性转成真实的原始属性类型。

  • 首先判断属性是否需要转换类型,如果不需要转直接应用于bean。比如:<property name="otherbean" ref="otherbean" /> 这种属性值其实是个字符串“otherbean” ,需要解析成容器中的otherbean实例的引用。
  • 如果属性值需要类型转换,比如:属性值是容器中的另外一个bean,则需要根据属性值解析出引用的对象然后注入到对象的属性上,应用到bean。

通过 beandefinitionvalueresolver 类中的 resolvevalueifnecessary()方法中进行属性值的解析, 对属性值的注入是通过 bw.setpropertyvalues()方法完成

解析: beandefinitionvalueresolver#resolvevalueifnecessary

给定一个 propertyvalue根据属性值进行类型解析,必要时解析对工厂中其他 bean 的引用

@nullable
	public object resolvevalueifnecessary(object argname, @nullable object value) {
		// we must check each value to see whether it requires a runtime reference
		// to another bean to be resolved.
		//对属性值是引用类型的解析
		if (value instanceof runtimebeanreference) {
			//比如:<property name="xx" ref="xxbean" 就是引用类型,会走这里
			runtimebeanreference ref = (runtimebeanreference) value;
			//对引用类型属性进行解析
			return resolvereference(argname, ref);
		}
		///对属性值是引用容器中另一个 bean 名称的解析
		else if (value instanceof runtimebeannamereference) {
			string refname = ((runtimebeannamereference) value).getbeanname();
			refname = string.valueof(doevaluate(refname));
			//判断容器中是否有这个bean
			if (!this.beanfactory.containsbean(refname)) {
				throw new beandefinitionstoreexception(
						"invalid bean name '" + refname + "' in bean reference for " + argname);
			}
			return refname;
		}
		else if (value instanceof beandefinitionholder) {
			// resolve beandefinitionholder: contains beandefinition with name and aliases.
			//解析 beandefinitionholder:包含带有名称和别名的 beandefinition
			beandefinitionholder bdholder = (beandefinitionholder) value;
			//解析内部 bean
			return resolveinnerbean(argname, bdholder.getbeanname(), bdholder.getbeandefinition());
		}
		else if (value instanceof beandefinition) {
			// resolve plain beandefinition, without contained name: use dummy name.
			//解析纯 beandefinition,不包含名称
			beandefinition bd = (beandefinition) value;
			string innerbeanname = "(inner bean)" + beanfactoryutils.generated_bean_name_separator +
					objectutils.getidentityhexstring(bd);
			return resolveinnerbean(argname, innerbeanname, bd);
		}
		//对数组类型解析
		else if (value instanceof managedarray) {
			// may need to resolve contained runtime references.
			managedarray array = (managedarray) value;
			class<?> elementtype = array.resolvedelementtype;
			if (elementtype == null) {
				string elementtypename = array.getelementtypename();
				if (stringutils.hastext(elementtypename)) {
					try {
						elementtype = classutils.forname(elementtypename, this.beanfactory.getbeanclassloader());
						array.resolvedelementtype = elementtype;
					}
					catch (throwable ex) {
						// improve the message by showing the context.
						throw new beancreationexception(
								this.beandefinition.getresourcedescription(), this.beanname,
								"error resolving array type for " + argname, ex);
					}
				}
				else {
					elementtype = object.class;
				}
			}
			return resolvemanagedarray(argname, (list<?>) value, elementtype);
		}
		//对集合类型解析
		else if (value instanceof managedlist) {
			// may need to resolve contained runtime references.
			return resolvemanagedlist(argname, (list<?>) value);
		}
		//对set类型解析
		else if (value instanceof managedset) {
			// may need to resolve contained runtime references.
			return resolvemanagedset(argname, (set<?>) value);
		}
		//对map类型解析
		else if (value instanceof managedmap) {
			// may need to resolve contained runtime references.
			return resolvemanagedmap(argname, (map<?, ?>) value);
		}
		//对properties解析
		else if (value instanceof managedproperties) {
			properties original = (properties) value;
			properties copy = new properties();
			original.foreach((propkey, propvalue) -> {
				if (propkey instanceof typedstringvalue) {
					propkey = evaluate((typedstringvalue) propkey);
				}
				if (propvalue instanceof typedstringvalue) {
					propvalue = evaluate((typedstringvalue) propvalue);
				}
				if (propkey == null || propvalue == null) {
					throw new beancreationexception(
							this.beandefinition.getresourcedescription(), this.beanname,
							"error converting properties key/value pair for " + argname + ": resolved to null");
				}
				copy.put(propkey, propvalue);
			});
			return copy;
		}
		//解析字符串类型的属性值
		else if (value instanceof typedstringvalue) {
			// convert value to target type here.
			typedstringvalue typedstringvalue = (typedstringvalue) value;
			object valueobject = evaluate(typedstringvalue);
			try {
				//目标类型
				class<?> resolvedtargettype = resolvetargettype(typedstringvalue);
				if (resolvedtargettype != null) {
					//目标类型进行解析
					return this.typeconverter.convertifnecessary(valueobject, resolvedtargettype);
				}
				else {
					//类型没获取到,就返回object类型
					return valueobject;
				}
			}
			catch (throwable ex) {
				// improve the message by showing the context.
				throw new beancreationexception(
						this.beandefinition.getresourcedescription(), this.beanname,
						"error converting typed string value for " + argname, ex);
			}
		}
		else if (value instanceof nullbean) {
			return null;
		}
		else {
			return evaluate(value);
		}
	}

这个方法中就是根据属性的值的类型进行解析,如:string,array,list,set,map的类型,比较复杂的就是属性值依赖的是一个bean,那么就需要根据依赖的bean的名字找到容器中的bean的实例,查找如下:

/**
	 * resolve a reference to another bean in the factory.
	 */
	 //关联对象的解析
	@nullable
	private object resolvereference(object argname, runtimebeanreference ref) {
		try {
			object bean;
			//引用对象的名称
			string refname = ref.getbeanname();
			refname = string.valueof(doevaluate(refname));
			//如果对象在父容器中,从父容器获取
			if (ref.istoparent()) {
				if (this.beanfactory.getparentbeanfactory() == null) {
					throw new beancreationexception(
							this.beandefinition.getresourcedescription(), this.beanname,
							"can't resolve reference to bean '" + refname +
									"' in parent factory: no parent factory available");
				}
				//如果对象在父容器中,从父容器获取
				bean = this.beanfactory.getparentbeanfactory().getbean(refname);
			}
			else {
				//[重要]根据依赖的bean的名字,从当前容器中获取bean
				bean = this.beanfactory.getbean(refname);
				//把依赖的bean的实例和当前对象建议依赖关系,使用 dependentbeanmap 去维护关系
				this.beanfactory.registerdependentbean(refname, this.beanname);
			}
			if (bean instanceof nullbean) {
				bean = null;
			}
			return bean;
		}
		catch (beansexception ex) {
			throw new beancreationexception(
					this.beandefinition.getresourcedescription(), this.beanname,
					"cannot resolve reference to bean '" + ref.getbeanname() + "' while setting " + argname, ex);
		}
	}


 * for each element in the managed array, resolve reference if necessary.
	 */
	 //解析数组
	private object resolvemanagedarray(object argname, list<?> ml, class<?> elementtype) {
		object resolved = array.newinstance(elementtype, ml.size());
		for (int i = 0; i < ml.size(); i++) {
			array.set(resolved, i, resolvevalueifnecessary(new keyedargname(argname, i), ml.get(i)));
		}
		return resolved;
	}

	/**
	 * for each element in the managed list, resolve reference if necessary.
	 */
	 //解析list
	private list<?> resolvemanagedlist(object argname, list<?> ml) {
		list<object> resolved = new arraylist<>(ml.size());
		for (int i = 0; i < ml.size(); i++) {
			resolved.add(resolvevalueifnecessary(new keyedargname(argname, i), ml.get(i)));
		}
		return resolved;
	}

	/**
	 * for each element in the managed set, resolve reference if necessary.
	 */
	 //解析set
	private set<?> resolvemanagedset(object argname, set<?> ms) {
		set<object> resolved = new linkedhashset<>(ms.size());
		int i = 0;
		for (object m : ms) {
			resolved.add(resolvevalueifnecessary(new keyedargname(argname, i), m));
			i++;
		}
		return resolved;
	}

	/**
	 * for each element in the managed map, resolve reference if necessary.
	 */
	 //解析map
	private map<?, ?> resolvemanagedmap(object argname, map<?, ?> mm) {
		map<object, object> resolved = new linkedhashmap<>(mm.size());
		mm.foreach((key, value) -> {
			object resolvedkey = resolvevalueifnecessary(argname, key);
			object resolvedvalue = resolvevalueifnecessary(new keyedargname(argname, key), value);
			resolved.put(resolvedkey, resolvedvalue);
		});
		return resolved;
	}

属性值解析完成之后 是封装成一个 mutablepropertyvalues,通过 beanwrapperimpl.setpropertyvalues()方法完成值的注入,beanwrapperimpl中注入方法又是由abstractpropertyaccessor#setpropertyvalue(java.lang.string, java.lang.object)去完成。

abstractpropertyaccessor#setpropertyvalue

@override
	public void setpropertyvalues(propertyvalues pvs, boolean ignoreunknown, boolean ignoreinvalid)
			throws beansexception {

		list<propertyaccessexception> propertyaccessexceptions = null;
		//拿到所有的属性列表
		list<propertyvalue> propertyvalues = (pvs instanceof mutablepropertyvalues ?
				((mutablepropertyvalues) pvs).getpropertyvaluelist() : arrays.aslist(pvs.getpropertyvalues()));
		for (propertyvalue pv : propertyvalues) {
			try {
				// this method may throw any beansexception, which won't be caught
				// here, if there is a critical failure such as no matching field.
				// we can attempt to deal only with less serious exceptions.
				//设置属性值
				setpropertyvalue(pv);
			}
			...省略...

@override
	public void setpropertyvalue(string propertyname, @nullable object value) throws beansexception {
		//属性访问器
		abstractnestablepropertyaccessor nestedpa;
		try {
			nestedpa = getpropertyaccessorforpropertypath(propertyname);
		}
		catch (notreadablepropertyexception ex) {
			throw new notwritablepropertyexception(getrootclass(), this.nestedpath + propertyname,
					"nested property in path '" + propertyname + "' does not exist", ex);
		}
		//属性助手
		propertytokenholder tokens = getpropertynametokens(getfinalpath(nestedpa, propertyname));
		//通过属性访问器为属性设置值
		nestedpa.setpropertyvalue(tokens, new propertyvalue(propertyname, value));
	}

这里看到,属性的注入交给了 abstractnestablepropertyaccessor 属性访问器去完成

protected void setpropertyvalue(propertytokenholder tokens, propertyvalue pv) throws beansexception {
		if (tokens.keys != null) {
			processkeyedproperty(tokens, pv);
		}
		else {
			//走这里
			processlocalproperty(tokens, pv);
		}
	}

private void processlocalproperty(propertytokenholder tokens, propertyvalue pv) {
		//属性处理器
		propertyhandler ph = getlocalpropertyhandler(tokens.actualname);
		if (ph == null || !ph.iswritable()) {
			if (pv.isoptional()) {
				if (logger.isdebugenabled()) {
					logger.debug("ignoring optional value for property '" + tokens.actualname +
							"' - property not found on bean class [" + getrootclass().getname() + "]");
				}
				return;
			}
			else {
				throw createnotwritablepropertyexception(tokens.canonicalname);
			}
		}

		object oldvalue = null;
		try {
			//原生值
			object originalvalue = pv.getvalue();
			object valuetoapply = originalvalue;
			...省略...
			//这是重点,通过 propertyhandler 把属性值设置给对象
			ph.setvalue(valuetoapply);
		}
		catch (typemismatchexception ex) {
			throw ex;
		}

这里的属性值通过 propertyhandler去设置

@override
	public void setvalue(@nullable object value) throws exception {
		//得到属性的set方法
		method writemethod = (this.pd instanceof generictypeawarepropertydescriptor ?
				((generictypeawarepropertydescriptor) this.pd).getwritemethodforactualaccess() :
				this.pd.getwritemethod());
		if (system.getsecuritymanager() != null) {
			accesscontroller.doprivileged((privilegedaction<object>) () -> {
				reflectionutils.makeaccessible(writemethod);
				return null;
			});
			try {
				accesscontroller.doprivileged((privilegedexceptionaction<object>)
						() -> writemethod.invoke(getwrappedinstance(), value), acc);
			}
			catch (privilegedactionexception ex) {
				throw ex.getexception();
			}
		}
		else {
			//设置访问权限
			reflectionutils.makeaccessible(writemethod);
			//调用set方法把属性值设置进去
			writemethod.invoke(getwrappedinstance(), value);
		}
	}

这里就是得到属性的set方法,然后调用set方法把值注入进去。

构造器注入参数

在之前分析bean的创建的时候我们就说到,在 abstractautowirecapablebeanfactory#createbeaninstance 中会通过反射获取到bean的构造器,如果是有参构造就会走autowireconstructor 方法,通过有参构造创建实例

protected beanwrapper createbeaninstance(string beanname, rootbeandefinition mbd, @nullable object[] args) {
		// make sure bean class is actually resolved at this point.
		class<?> beanclass = resolvebeanclass(mbd, beanname);

		...省略...
		// need to determine the constructor...
		constructor<?>[] ctors = determineconstructorsfrombeanpostprocessors(beanclass, beanname);
		if (ctors != null ||
				mbd.getresolvedautowiremode() == rootbeandefinition.autowire_constructor ||
				mbd.hasconstructorargumentvalues() || !objectutils.isempty(args))  {
				//【重要】构造器注入参数
			return autowireconstructor(beanname, mbd, ctors, args);
		}

		// no special handling: simply use no-arg constructor.
		return instantiatebean(beanname, mbd);
	}

在autowireconstructor方法中会通过 constructorresolver 对构造器参数进行解析

protected beanwrapper autowireconstructor(
			string beanname, rootbeandefinition mbd, @nullable constructor<?>[] ctors, @nullable object[] explicitargs) {
		//构造器解析器,注入
		return new constructorresolver(this).autowireconstructor(beanname, mbd, ctors, explicitargs);
	}


public beanwrapper autowireconstructor(final string beanname, final rootbeandefinition mbd,
			@nullable constructor<?>[] chosenctors, @nullable final object[] explicitargs) {

		...省略...
			else {
				//得到构造器参数
				constructorargumentvalues cargs = mbd.getconstructorargumentvalues();
				//得到构造器参数值
				resolvedvalues = new constructorargumentvalues();
				//解析参数值【重要】
				minnrofargs = resolveconstructorarguments(beanname, mbd, bw, cargs, resolvedvalues);
			}
		...省略...
try {
			//实例化策略
			final instantiationstrategy strategy = beanfactory.getinstantiationstrategy();
			object beaninstance;

			if (system.getsecuritymanager() != null) {
				final constructor<?> ctortouse = constructortouse;
				final object[] argumentstouse = argstouse;
				beaninstance = accesscontroller.doprivileged((privilegedaction<object>) () ->
						strategy.instantiate(mbd, beanname, beanfactory, ctortouse, argumentstouse),
						beanfactory.getaccesscontrolcontext());
			}
			else {
				//实例化对象,根据有参构造器,使用反射创建实例
				beaninstance = strategy.instantiate(mbd, beanname, this.beanfactory, constructortouse, argstouse);
			}

			bw.setbeaninstance(beaninstance);
			return bw;
		}

resolveconstructorarguments 方法中又通过 beandefinitionvalueresolver来解析属性值,有参数的值了,就会走反射,根据有参构造器创建实例返回。

private int resolveconstructorarguments(string beanname, rootbeandefinition mbd, beanwrapper bw,
			constructorargumentvalues cargs, constructorargumentvalues resolvedvalues) {

		typeconverter customconverter = this.beanfactory.getcustomtypeconverter();
		typeconverter converter = (customconverter != null ? customconverter : bw);
		//属性值的解析器
		beandefinitionvalueresolver valueresolver =
				new beandefinitionvalueresolver(this.beanfactory, beanname, mbd, converter);

		...省略...
		for (constructorargumentvalues.valueholder valueholder : cargs.getgenericargumentvalues()) {
			if (valueholder.isconverted()) {
				resolvedvalues.addgenericargumentvalue(valueholder);
			}
			else {
			//为构造器参数值做解析,这里和之前分析的set注入的属性值解析就一样了
				object resolvedvalue =
						valueresolver.resolvevalueifnecessary("constructor argument", valueholder.getvalue());
				constructorargumentvalues.valueholder resolvedvalueholder = new constructorargumentvalues.valueholder(
						resolvedvalue, valueholder.gettype(), valueholder.getname());
				resolvedvalueholder.setsource(valueholder);
				resolvedvalues.addgenericargumentvalue(resolvedvalueholder);
			}
		}

		return minnrofargs;
	}

因为之前 resolvevalueifnecessary方法已经分析过了,这里就不多说了。

总结

到这里属性注入的流程就分析完了,总结都在这个图上

Spring Bean的实例化之属性注入源码剖析过程

喜欢的话就给个好评吧,你的肯定是我坚持写作最大的动力,来吧兄弟们,给我一点动力

以上就是spring bean的实例化之属性注入源码剖析过程的详细内容,更多关于spring bean 实例化属性注入的资料请关注其它相关文章!