4 IoC容器的依赖注入(2)

前端之家收集整理的这篇文章主要介绍了4 IoC容器的依赖注入(2)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

相对于Bean的创建过程,注入过程显得简单而清晰的多。

注入的过程整体分为两个阶段:

第一个阶段是依据BeanDefition定义的property找到相关的属性值,这个过程中如果定义了autowireByName 或者autowireByType 优先进行这两个定义的查找,然后进行正常匹配,也就是我们定义的<property>,这个部分会覆盖掉autowire的内容。以上所有找到的属性值都会放到一个deepcopy容器里面。

第二个阶段就是把deepcopy容器的值注入到bean中。

1 populateBean 依赖注入的入口

在这个方法注册了后处理方法,并且完成了autowire定义的属性值的获取

protected void populateBean(String beanName,RootBeanDefinition mbd,BeanWrapper bw) {
	//获得所有的属性集合
		PropertyValues pvs = mbd.getPropertyValues();

		if (bw == null) {
			if (!pvs.isEmpty()) {
				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.
		boolean continueWithPropertyPopulation = true;
		//	注册后处理方法
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(),beanName)) {
						continueWithPropertyPopulation = false;
						break;
					}
				}
			}
		}

		if (!continueWithPropertyPopulation) {
			return;
		}
		//优先设置自动装配 
		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
			MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

			// Add property values based on autowire by name if applicable.
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
				autowireByName(beanName,mbd,bw,newPvs);
			}

			// Add property values based on autowire by type if applicable.
			if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
				autowireByType(beanName,newPvs);
			}
		//从自动装配方法中获得需要注入的属性  如果配置了普通的属性注入 这些值将会在后面被覆盖
			pvs = newPvs;
		}

		boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
		boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
		//在这处理普通的依赖注入  会覆盖掉之前自动装配的结果
		if (hasInstAwareBpps || needsDepCheck) {
			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw,mbd.allowCaching);
			if (hasInstAwareBpps) {
				for (BeanPostProcessor bp : getBeanPostProcessors()) {
					if (bp instanceof InstantiationAwareBeanPostProcessor) {
						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
						pvs = ibp.postProcessPropertyValues(pvs,filteredPds,bw.getWrappedInstance(),beanName);
						if (pvs == null) {
							return;
						}
					}
				}
			}
			if (needsDepCheck) {
				checkDependencies(beanName,pvs);
			}
		}
		//依赖注入的入口
		applyPropertyValues(beanName,pvs);
	}

2 autowireByName

根据名字自动注入

protected void autowireByName(
			String beanName,AbstractBeanDefinition mbd,BeanWrapper bw,MutablePropertyValues pvs) {

		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd,bw);
		//遍历自动状态的名字  从当前的容器中寻找对应的Bean,如果能找到,就把这个值放入属性值容器中 用于后面的注入行为
		for (String propertyName : propertyNames) {
			if (containsBean(propertyName)) {
				Object bean = getBean(propertyName);
				pvs.add(propertyName,bean);
				registerDependentBean(propertyName,beanName);
				if (logger.isDebugEnabled()) {
					logger.debug("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");
				}
			}
		}
	}

3 autowireByType

根据类型自动注入,核心方法是doResolveDependency

protected void autowireByType(
			String beanName,MutablePropertyValues pvs) {

		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}

		Set<String> autowiredBeanNames = new LinkedHashSet<String>(4);
		String[] propertyNames = unsatisfiedNonSimpleProperties(mbd,bw);
		for (String propertyName : propertyNames) {
			try {
				PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
				//Spring规定不能使用Object类型的 自动装配
				if (!Object.class.equals(pd.getPropertyType())) {
					MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
					// Do not allow eager init for type matching in case of a prioritized post-processor.
					boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
					//构造一个autowirebyType的处理器,用于找到对应的注入的Bean
					DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam,eager);
					// 处理自动装配 找到对应的属性值
					Object autowiredArgument = resolveDependency(desc,autowiredBeanNames,converter);
					if (autowiredArgument != null) {
						pvs.add(propertyName,autowiredArgument);
					}
					for (String autowiredBeanName : autowiredBeanNames) {
						registerDependentBean(autowiredBeanName,beanName);
						if (logger.isDebugEnabled()) {
							logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
									propertyName + "' to bean named '" + autowiredBeanName + "'");
						}
					}
					autowiredBeanNames.clear();
				}
			}
			catch (BeansException ex) {
				throw new UnsatisfiedDependencyException(mbd.getResourceDescription(),propertyName,ex);
			}
		}
	}

4 doResolveDependency

这个方法处理byType自动注入的值获取过程。分别处理了 array collection(list 和set) map等数组和集合类型的自动注入。对于这个注入过程,所有的集合和Map类型的set注入方法必须定义为接口类型,如果定义为他们的实现类,就无法完成注入

public Object doResolveDependency(DependencyDescriptor descriptor,String beanName,Set<String> autowiredBeanNames,TypeConverter typeConverter) throws BeansException {

		Class<?> type = descriptor.getDependencyType();
		Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
		if (value != null) {
			if (value instanceof String) {
				String strVal = resolveEmbeddedValue((String) value);
				BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
				value = evaluateBeanDefinitionString(strVal,bd);
			}
			TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
			return (descriptor.getField() != null ?
					converter.convertIfNecessary(value,type,descriptor.getField()) :
					converter.convertIfNecessary(value,descriptor.getMethodParameter()));
		}
		//对数组类型的自动注入
		if (type.isArray()) {
			Class<?> componentType = type.getComponentType();
			DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
			targetDesc.increaseNestingLevel();
			Map<String,Object> matchingBeans = findAutowireCandidates(beanName,componentType,targetDesc);
			if (matchingBeans.isEmpty()) {
				if (descriptor.isrequired()) {
					raiseNoSuchBeanDefinitionException(componentType,"array of " + componentType.getName(),descriptor);
				}
				return null;
			}
			if (autowiredBeanNames != null) {
				autowiredBeanNames.addAll(matchingBeans.keySet());
			}
			TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
			Object result = converter.convertIfNecessary(matchingBeans.values(),type);
			if (getDependencyComparator() != null && result instanceof Object[]) {
				Arrays.sort((Object[]) result,adaptDependencyComparator(matchingBeans));
			}
			return result;
		}
		//对集合类型的注入  这里的集合对应的set方法必须定义为set list这样的接口类型
		// 如果定义为他们的实现类  将不能完成注入  
		// 对于集合的注入  spring将搜索配置文件中所有定义为集合泛型类型的bean 注入
		// 如果没有定义泛型  也不能完成注入
		else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
			Class<?> elementType = descriptor.getCollectionType();
			if (elementType == null) {
				if (descriptor.isrequired()) {
					throw new FatalBeanException("No element type declared for collection [" + type.getName() + "]");
				}
				return null;
			}
			DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
			targetDesc.increaseNestingLevel();
			Map<String,elementType,targetDesc);
			if (matchingBeans.isEmpty()) {
				if (descriptor.isrequired()) {
					raiseNoSuchBeanDefinitionException(elementType,"collection of " + elementType.getName(),type);
			if (getDependencyComparator() != null && result instanceof List) {
				Collections.sort((List<?>) result,adaptDependencyComparator(matchingBeans));
			}
			return result;
		}
		//Map类型也必须定义为接口类型
		else if (Map.class.isAssignableFrom(type) && type.isInterface()) {
			Class<?> keyType = descriptor.getMapKeyType();
			if (keyType == null || !String.class.isAssignableFrom(keyType)) {
				if (descriptor.isrequired()) {
					throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() +
							"] must be assignable to [java.lang.String]");
				}
				return null;
			}
			Class<?> valueType = descriptor.getMapValueType();
			if (valueType == null) {
				if (descriptor.isrequired()) {
					throw new FatalBeanException("No value type declared for map [" + type.getName() + "]");
				}
				return null;
			}
			DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor);
			targetDesc.increaseNestingLevel();
			Map<String,valueType,targetDesc);
			if (matchingBeans.isEmpty()) {
				if (descriptor.isrequired()) {
					raiseNoSuchBeanDefinitionException(valueType,"map with value type " + valueType.getName(),descriptor);
				}
				return null;
			}
			if (autowiredBeanNames != null) {
				autowiredBeanNames.addAll(matchingBeans.keySet());
			}
			return matchingBeans;
		}
		// 对于其他类型
		else {
			//首先找到所有符合类型定义的Bean
			Map<String,descriptor);
			//如果没有找到 并且这个属性还是required 抛出异常
			if (matchingBeans.isEmpty()) {
				if (descriptor.isrequired()) {
					raiseNoSuchBeanDefinitionException(type,"",descriptor);
				}
				return null;
			}
			//如果结果不唯一  查看有没有定义primary的  如果没有定义  抛出不唯一的异常
			if (matchingBeans.size() > 1) {
				String primaryBeanName = determineAutowireCandidate(matchingBeans,descriptor);
				if (primaryBeanName == null) {
					throw new NoUniqueBeanDefinitionException(type,matchingBeans.keySet());
				}
				if (autowiredBeanNames != null) {
					autowiredBeanNames.add(primaryBeanName);
				}
				return matchingBeans.get(primaryBeanName);
			}
			// 对于唯一的结果 放入属性集合
			Map.Entry<String,Object> entry = matchingBeans.entrySet().iterator().next();
			if (autowiredBeanNames != null) {
				autowiredBeanNames.add(entry.getKey());
			}
			return entry.getValue();
		}
	}

	

5 applyPropertyValues 获取属性值的过程

这个方法获取属性值的主要方法 这里主要利用了BeanDefinitionValueResolver进行了属性值转换,将属性值与BeanDefition中定义的需要的值连接在一起,放入deepcopy容器中

/**
	 * Apply the given property values,resolving any runtime references
	 * to other beans in this bean factory. Must use deep copy,so we
	 * don't permanently modify this property.
	 * @param beanName the bean name passed for better exception information
	 * @param mbd the merged bean definition
	 * @param bw the BeanWrapper wrapping the target object
	 * @param pvs the new property values
	 */
	protected void applyPropertyValues(String beanName,BeanDefinition mbd,PropertyValues pvs) {
		if (pvs == null || pvs.isEmpty()) {
			return;
		}
		//
		MutablePropertyValues mpvs = null;
		//原始属性值
		List<PropertyValue> original;

		if (System.getSecurityManager() != null) {
			if (bw instanceof BeanWrapperImpl) {
				((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
			}
		}

		if (pvs instanceof MutablePropertyValues) {
			mpvs = (MutablePropertyValues) pvs;
			if (mpvs.isConverted()) {
				// Shortcut: use the pre-converted values as-is.
				try {
					bw.setPropertyValues(mpvs);
					return;
				}
				catch (BeansException ex) {
					throw new BeanCreationException(
							mbd.getResourceDescription(),"Error setting property values",ex);
				}
			}
			original = mpvs.getPropertyValueList();
		}
		else {
			original = Arrays.asList(pvs.getPropertyValues());
		}

		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}
		//属性值转换器  需要将注入的属性值转换为beanDefition定义的属性值
		BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this,converter);

		// 建立一个属性值的深拷贝  保存所有转换过的属性值
		List<PropertyValue> deepCopy = new ArrayList<PropertyValue>(original.size());
		boolean resolveNecessary = false;
		for (PropertyValue pv : original) {
			//如果已经处理过,直接放入list中
			if (pv.isConverted()) {
				deepCopy.add(pv);
			}
			else {
				String propertyName = pv.getName();
				Object originalValue = pv.getValue();
				//第一次转换
				Object resolvedValue = valueResolver.resolveValueIfNecessary(pv,originalValue);
				Object convertedValue = resolvedValue;
				boolean convertible = bw.isWritableProperty(propertyName) &&
						!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
				if (convertible) {
					//第二次转换
					convertedValue = convertForProperty(resolvedValue,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.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;
					deepCopy.add(new PropertyValue(pv,convertedValue));
				}
			}
		}
		if (mpvs != null && !resolveNecessary) {
			mpvs.setConverted();
		}

		// Set our (possibly massaged) deep copy.
		try {
			//将转换过的值注入到到Bean中
			bw.setPropertyValues(new MutablePropertyValues(deepCopy));
		}
		catch (BeansException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(),ex);
		}
	}

6 resolveValueIfNecessary属性值转换器

这里根据不同类型的属性值的定义,分别去处理这个属性

/*
Given a PropertyValue,return a value,resolving any references to other beans in the factory if necessary. The value could be: 

A BeanDefinition,which leads to the creation of a corresponding new bean instance. Singleton flags and names of such "inner beans" are always ignored: Inner beans are anonymous prototypes. 
A RuntimeBeanReference,which must be resolved. 
A ManagedList. This is a special collection that may contain RuntimeBeanReferences or Collections that will need to be resolved. 
A ManagedSet. May also contain RuntimeBeanReferences or Collections that will need to be resolved. 
A ManagedMap. In this case the value may be a RuntimeBeanReference or Collection that will need to be resolved. 
An ordinary object or null,in which case it's left alone.

*/
public Object resolveValueIfNecessary(Object argName,Object value) {
		/**
			处理最常见的一类注入  注入的对象是容器中的另一个bean
			这里成为runtime reference 
		*/
		if (value instanceof RuntimeBeanReference) {
			RuntimeBeanReference ref = (RuntimeBeanReference) value;
			return resolveReference(argName,ref);
		}
		else if (value instanceof RuntimeBeanNameReference) {
			String refName = ((RuntimeBeanNameReference) value).getBeanName();
			refName = String.valueOf(doEvaluate(refName));
			if (!this.beanfactory.containsBean(refName)) {
				throw new BeanDefinitionStoreException(
						"Invalid bean name '" + refName + "' in bean reference for " + argName);
			}
			return refName;
		}
		/**
		下面两个都是在处理嵌套定义的bean
		*/
		else if (value instanceof BeanDefinitionHolder) {
			// Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
			//这里处理的是正式定义的bean 有id
			BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
			return resolveInnerBean(argName,bdHolder.getBeanName(),bdHolder.getBeanDefinition());
		}
		
		else if (value instanceof BeanDefinition) {
			// Resolve plain BeanDefinition,without contained name: use dummy name.
			//这里处理的是匿名的bean
			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);
		}
		//对list的处理
		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);
		}
		//对property集合的处理  不需要转换  直接放入copy中
		else if (value instanceof ManagedProperties) {
			Properties original = (Properties) value;
			Properties copy = new Properties();
			for (Map.Entry<Object,Object> propEntry : original.entrySet()) {
				Object propKey = propEntry.getKey();
				Object propValue = propEntry.getValue();
				if (propKey instanceof TypedStringValue) {
					propKey = evaluate((TypedStringValue) propKey);
				}
				if (propValue instanceof TypedStringValue) {
					propValue = evaluate((TypedStringValue) propValue);
				}
				copy.put(propKey,propValue);
			}
			return copy;
		}
		/**
		对于其他常量的处理  String int boolean 等类型  
		对他们的处理不需要借助于额外的转换器 仅需调用evaluate生成对应值即可
		*/
		//对String类型的处理
		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 {
					return valueObject;
				}
			}
			catch (Throwable ex) {
				// Improve the message by showing the context.
				throw new BeanCreationException(
						this.beanDefinition.getResourceDescription(),"Error converting typed String value for " + argName,ex);
			}
		}
		//对于其他值的处理  
		else {
			return evaluate(value);
		}
	}

7 setPropertyValue 注入属性值的过程

这里主要是通过反射将前面得到的属性值注入到Bean中

private void setPropertyValue(PropertyTokenHolder tokens,PropertyValue pv) throws BeansException {
		String propertyName = tokens.canonicalName;
		String actualName = tokens.actualName;

		/** 对 array   list  map  这三种类型的处理 
			这三种类型的注入并不是通过set方法的反射完成
			而是直接通过Java的对这些类的反射方法 直接修改对应属性值
		*/
		if (tokens.keys != null) {
			//下面十几行的作用是在找到集合或者数组的属性名  
			// Apply indexes and map keys: fetch value for all keys but the last one.
			PropertyTokenHolder getterTokens = new PropertyTokenHolder();
			getterTokens.canonicalName = tokens.canonicalName;
			getterTokens.actualName = tokens.actualName;
			getterTokens.keys = new String[tokens.keys.length - 1];
			System.arraycopy(tokens.keys,getterTokens.keys,tokens.keys.length - 1);
			Object propValue;
			try {
				propValue = getPropertyValue(getterTokens);
			}
			catch (NotReadablePropertyException ex) {
				throw new NotWritablePropertyException(getRootClass(),this.nestedPath + propertyName,"Cannot access indexed value in property referenced " +
						"in indexed property path '" + propertyName + "'",ex);
			}
			// Set value for last key.
			String key = tokens.keys[tokens.keys.length - 1];
			if (propValue == null) {
				// null map value case
				if (isAutoGrowNestedPaths()) {
					// TODO: cleanup,this is pretty hacky
					int lastKeyIndex = tokens.canonicalName.lastIndexOf('[');
					getterTokens.canonicalName = tokens.canonicalName.substring(0,lastKeyIndex);
					propValue = setDefaultValue(getterTokens);
				}
				else {
					throw new NullValueInNestedPathException(getRootClass(),"Cannot access indexed value in property referenced " +
							"in indexed property path '" + propertyName + "': returned null");
				}
			}
			//对于数组的注入
			if (propValue.getClass().isArray()) {
				PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
				Class<?> requiredType = propValue.getClass().getComponentType();
				int arrayIndex = Integer.parseInt(key);
				Object oldValue = null;
				try {
					if (isExtractOldValueForEditor() && arrayIndex < Array.getLength(propValue)) {
						oldValue = Array.get(propValue,arrayIndex);
					}
					Object convertedValue = convertIfNecessary(propertyName,oldValue,pv.getValue(),requiredType,TypeDescriptor.nested(property(pd),tokens.keys.length));
					int length = Array.getLength(propValue);
					if (arrayIndex >= length && arrayIndex < this.autoGrowCollectionLimit) {
						Class<?> componentType = propValue.getClass().getComponentType();
						Object newArray = Array.newInstance(componentType,arrayIndex + 1);
						System.arraycopy(propValue,newArray,length);
						setPropertyValue(actualName,newArray);
						propValue = getPropertyValue(actualName);
					}
					//通过Java 反射包下面Array类进行对应的值的修改
					Array.set(propValue,arrayIndex,convertedValue);
				}
				catch (IndexOutOfBoundsException ex) {
					throw new InvalidPropertyException(getRootClass(),"Invalid array index in property path '" + propertyName + "'",ex);
				}
			}
			//对list进行注入
			else if (propValue instanceof List) {
				PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
				Class<?> requiredType = GenericCollectionTypeResolver.getCollectionReturnType(
						pd.getReadMethod(),tokens.keys.length);
				List<Object> list = (List<Object>) propValue;
				int index = Integer.parseInt(key);
				Object oldValue = null;
				if (isExtractOldValueForEditor() && index < list.size()) {
					oldValue = list.get(index);
				}
				Object convertedValue = convertIfNecessary(propertyName,tokens.keys.length));
				int size = list.size();
				if (index >= size && index < this.autoGrowCollectionLimit) {
					for (int i = size; i < index; i++) {
						try {
							list.add(null);
						}
						catch (NullPointerException ex) {
							throw new InvalidPropertyException(getRootClass(),"Cannot set element with index " + index + " in List of size " +
									size + ",accessed using property path '" + propertyName +
									"': List does not support filling up gaps with null elements");
						}
					}
					list.add(convertedValue);
				}
				else {
					try {
						//直接对获取到的list进行赋值
						list.set(index,convertedValue);
					}
					catch (IndexOutOfBoundsException ex) {
						throw new InvalidPropertyException(getRootClass(),"Invalid list index in property path '" + propertyName + "'",ex);
					}
				}
			}
			//对map进行注入
			else if (propValue instanceof Map) {
				PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
				Class<?> mapKeyType = GenericCollectionTypeResolver.getMapKeyReturnType(
						pd.getReadMethod(),tokens.keys.length);
				Class<?> mapValueType = GenericCollectionTypeResolver.getMapValueReturnType(
						pd.getReadMethod(),tokens.keys.length);
				Map<Object,Object> map = (Map<Object,Object>) propValue;
				// IMPORTANT: Do not pass full property name in here - property editors
				// must not kick in for map keys but rather only for map values.
				TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(mapKeyType);
				Object convertedMapKey = convertIfNecessary(null,null,key,mapKeyType,typeDescriptor);
				Object oldValue = null;
				if (isExtractOldValueForEditor()) {
					oldValue = map.get(convertedMapKey);
				}
				// Pass full property name and old value in here,since we want full
				// conversion ability for map values.
				Object convertedMapValue = convertIfNecessary(propertyName,mapValueType,tokens.keys.length));
				//直接对获取到的map进行赋值
				map.put(convertedMapKey,convertedMapValue);
			}
			else {
				throw new InvalidPropertyException(getRootClass(),"Property referenced in indexed property path '" + propertyName +
						"' is neither an array nor a List nor a Map; returned value was [" + pv.getValue() + "]");
			}
		}
		//对于非集合类型的注入
		else {
			PropertyDescriptor pd = pv.resolvedDescriptor;
			if (pd == null || !pd.getWriteMethod().getDeclaringClass().isInstance(this.object)) {
				pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
				if (pd == null || pd.getWriteMethod() == null) {
					if (pv.isOptional()) {
						logger.debug("Ignoring optional value for property '" + actualName +
								"' - property not found on bean class [" + getRootClass().getName() + "]");
						return;
					}
					else {
						PropertyMatches matches = PropertyMatches.forProperty(propertyName,getRootClass());
						throw new NotWritablePropertyException(
								getRootClass(),matches.buildErrorMessage(),matches.getPossibleMatches());
					}
				}
				pv.getOriginalPropertyValue().resolvedDescriptor = pd;
			}

			Object oldValue = null;
			try {
				Object originalValue = pv.getValue();
				Object valueToApply = originalValue;
				if (!Boolean.FALSE.equals(pv.conversionNecessary)) {
					if (pv.isConverted()) {
						valueToApply = pv.getConvertedValue();
					}
					else {
						if (isExtractOldValueForEditor() && pd.getReadMethod() != null) {
							//通过反射获取对应的set方法
							final Method readMethod = pd.getReadMethod();
							if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers()) &&
									!readMethod.isAccessible()) {
								if (System.getSecurityManager()!= null) {
									AccessController.doPrivileged(new PrivilegedAction<Object>() {
										@Override
										public Object run() {
											//提升方法的访问权限  
											readMethod.setAccessible(true);
											return null;
										}
									});
								}
								else {
									readMethod.setAccessible(true);
								}
							}
							try {
								if (System.getSecurityManager() != null) {
									oldValue = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
										@Override
										public Object run() throws Exception {
											//通过反射驱动set方法注入
											return readMethod.invoke(object);
										}
									},acc);
								}
								else {
									oldValue = readMethod.invoke(object);
								}
							}
							catch (Exception ex) {
								if (ex instanceof PrivilegedActionException) {
									ex = ((PrivilegedActionException) ex).getException();
								}
								if (logger.isDebugEnabled()) {
									logger.debug("Could not read prevIoUs value of property '" +
											this.nestedPath + propertyName + "'",ex);
								}
							}
						}
						valueToApply = convertForProperty(
								propertyName,originalValue,new TypeDescriptor(property(pd)));
					}
					pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
				}
				final Method writeMethod = (pd instanceof GenericTypeAwarePropertyDescriptor ?
						((GenericTypeAwarePropertyDescriptor) pd).getWriteMethodForActualAccess() :
						pd.getWriteMethod());
				if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers()) && !writeMethod.isAccessible()) {
					if (System.getSecurityManager()!= null) {
						AccessController.doPrivileged(new PrivilegedAction<Object>() {
							@Override
							public Object run() {
								writeMethod.setAccessible(true);
								return null;
							}
						});
					}
					else {
						writeMethod.setAccessible(true);
					}
				}
				final Object value = valueToApply;
				if (System.getSecurityManager() != null) {
					try {
						AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
							@Override
							public Object run() throws Exception {
								writeMethod.invoke(object,value);
								return null;
							}
						},acc);
					}
					catch (PrivilegedActionException ex) {
						throw ex.getException();
					}
				}
				else {
					writeMethod.invoke(this.object,value);
				}
			}
			catch (TypeMismatchException ex) {
				throw ex;
			}
			catch (InvocationTargetException ex) {
				PropertyChangeEvent propertyChangeEvent =
						new PropertyChangeEvent(this.rootObject,pv.getValue());
				if (ex.getTargetException() instanceof ClassCastException) {
					throw new TypeMismatchException(propertyChangeEvent,pd.getPropertyType(),ex.getTargetException());
				}
				else {
					throw new MethodInvocationException(propertyChangeEvent,ex.getTargetException());
				}
			}
			catch (Exception ex) {
				PropertyChangeEvent pce =
						new PropertyChangeEvent(this.rootObject,pv.getValue());
				throw new MethodInvocationException(pce,ex);
			}
		}
	}

8 getReadMethod

 public synchronized Method getReadMethod() {
	Method readMethod = getReadMethod0();
	if (readMethod == null) {
	    Class cls = getClass0();
	    if (cls == null || (readMethodName == null && readMethodRef == null)) {
		// The read method was explicitly set to null.
		return null;
	    }
	    if (readMethodName == null) {
		Class type = getPropertyType0();
		if (type == boolean.class || type == null) {
		    readMethodName = "is" + getBaseName();//boolean类型 方法使用is开头
		} else {
		    readMethodName = "get" + getBaseName();//get方法
		}
	    }
	    
	    // Since there can be multiple write methods but only one getter
	    // method,find the getter method first so that you know what the
	    // property type is.  For booleans,there can be "is" and "get"
	    // methods.  If an "is" method exists,this is the official
	    // reader method so look for this one first.
	    readMethod = Introspector.findMethod(cls,readMethodName,0);
	    if (readMethod == null) {
		readMethodName = "get" + getBaseName();
		readMethod = Introspector.findMethod(cls,0);
	    }
	    try {
		setReadMethod(readMethod);
	    } catch (IntrospectionException ex) {
		// fall
	    }
	}
	return readMethod;
    }
原文链接:https://www.f2er.com/javaschema/284567.html

猜你在找的设计模式相关文章