相对于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; }