【spring】深入IOC(2)

【spring】深入IOC(2)

在完成了对用户定义的bean信息的载入后,即IOC容器初始化完成,我们就可以通过依赖注入来使用这些bean对象了

而依赖注入的过程是用户第一次向IOC容器索要bean时触发的,当然通过设置lazy-init的属性也是可以实现bean的预实例化的

通过getBean接口,就会触发依赖注入的发生

对于单例情况,单例实例的维护是通过DefaultSingletonBeanRegistry 来管理的,其中构建了一个ConcurrentHashMap 来管理
/** Cache of singleton objects: bean name --> bean instance */
        private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>();

org.springframework.beans.factory.support.AbstractBeanFactory.class
public Object getBean(String name) throws BeansException {
             return doGetBean(name, null, null , false);
      }
protected <T> T doGetBean(
                   final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
                   throws BeansException {

             final String beanName = transformedBeanName(name);
            Object bean;

             // Eagerly check singleton cache for manually registered singletons.
// 先从缓存取单例的bean
            Object sharedInstance = getSingleton(beanName);
             if (sharedInstance != null && args == null) {
                   if (logger .isDebugEnabled()) {
                         if (isSingletonCurrentlyInCreation(beanName)) {
                               logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                                           "' that is not fully initialized yet - a consequence of a circular reference");
                        }
                         else {
                               logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
                        }
                  }
                  bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
            }

             else {
                   // Fail if we're already creating this bean instance:
                   // We're assumably within a circular reference.
                   if (isPrototypeCurrentlyInCreation(beanName)) {
                         throw new BeanCurrentlyInCreationException(beanName);
                  }
// 一直顺着双亲BeanFactory链来查找能否在工厂中取到需要的bean
                   // Check if bean definition exists in this factory.
                  BeanFactory parentBeanFactory = getParentBeanFactory();
                   if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                         // Not found -> check parent.
                        String nameToLookup = originalBeanName(name);
                         if (args != null) {
                               // Delegation to parent with explicit args.
                               return (T) parentBeanFactory.getBean(nameToLookup, args);
                        }
                         else {
                               // No args -> delegate to standard getBean method.
                               return parentBeanFactory.getBean(nameToLookup, requiredType);
                        }
                  }

                   if (!typeCheckOnly) {
                        markBeanAsCreated(beanName);
                  }

                   final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                  checkMergedBeanDefinition(mbd, beanName, args);

                   // Guarantee initialization of beans that the current bean depends on.
// 取依赖bean,会一直触发getBean的递归调用,实现依赖注入,直至一个没有任何依赖的bean
                  String[] dependsOn = mbd.getDependsOn();
                   if (dependsOn != null) {
                         for (String dependsOnBean : dependsOn) {
                              getBean(dependsOnBean);
                              registerDependentBean(dependsOnBean, beanName);
                        }
                  }

                   // Create bean instance.
// 通过createBean 创建单例bean实例
                   if (mbd.isSingleton()) {
                        sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                               public Object getObject() throws BeansException {
                                     try {
                                           return createBean(beanName, mbd, args);
                                    }
                                     catch (BeansException ex) {
                                           // Explicitly remove instance from singleton cache: It might have been put there
                                           // eagerly by the creation process, to allow for circular reference resolution.
                                           // Also remove any beans that received a temporary reference to the bean.
                                          destroySingleton(beanName);
                                           throw ex;
                                    }
                              }
                        });
                        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                  }
// 对原型实例则直接创建bean实例
                   else if (mbd.isPrototype()) {
                         // It's a prototype -> create a new instance.
                        Object prototypeInstance = null;
                         try {
                              beforePrototypeCreation(beanName);
                              prototypeInstance = createBean(beanName, mbd, args);
                        }
                         finally {
                              afterPrototypeCreation(beanName);
                        }
                        bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                  }

                   else {
                        String scopeName = mbd.getScope();
                         final Scope scope = this.scopes.get(scopeName);
                         if (scope == null) {
                               throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
                        }
                         try {
                              Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
                                     public Object getObject() throws BeansException {
                                          beforePrototypeCreation(beanName);
                                           try {
                                                 return createBean(beanName, mbd, args);
                                          }
                                           finally {
                                                afterPrototypeCreation(beanName);
                                          }
                                    }
                              });
                              bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                        }
                         catch (IllegalStateException ex) {
                               throw new BeanCreationException(beanName,
                                           "Scope '" + scopeName + "' is not active for the current thread; " +
                                           "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                                          ex);
                        }
                  }
            }

             // Check if required type matches the type of the actual bean instance.
             if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
                   try {
                         return getTypeConverter().convertIfNecessary(bean, requiredType);
                  }
                   catch (TypeMismatchException ex) {
                         if (logger .isDebugEnabled()) {
                               logger.debug("Failed to convert bean '" + name + "' to required type [" +
                                          ClassUtils. getQualifiedName(requiredType) + "]", ex);
                        }
                         throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                  }
            }
             return (T) bean;
      }

// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.class
// createBean方法中通过调用doCreateBean方法来实际进行bean的创建过程
protected Object doCreateBean( final String beanName, final RootBeanDefinition mbd, final Object[] args) {
             // Instantiate the bean.
// 通过BeanWrapper来持有所创建的bean对象
            BeanWrapper instanceWrapper = null;
             if (mbd.isSingleton()) {
                  instanceWrapper = this.factoryBeanInstanceCache .remove(beanName);
            }
             if (instanceWrapper == null) {
// 通过createBeanInstance方法来创建bean
                  instanceWrapper = createBeanInstance(beanName, mbd, args);
            }
             final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
            Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null );

             // Allow post-processors to modify the merged bean definition.
             synchronized (mbd.postProcessingLock ) {
                   if (!mbd.postProcessed ) {
                        applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                        mbd. postProcessed = true ;
                  }
            }

             // Eagerly cache singletons to be able to resolve circular references
             // even when triggered by lifecycle interfaces like BeanFactoryAware.
             boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
                        isSingletonCurrentlyInCreation(beanName));
             if (earlySingletonExposure) {
                   if (logger .isDebugEnabled()) {
                         logger.debug("Eagerly caching bean '" + beanName +
                                     "' to allow for resolving potential circular references");
                  }
                  addSingletonFactory(beanName, new ObjectFactory() {
                         public Object getObject() throws BeansException {
                               return getEarlyBeanReference(beanName, mbd, bean);
                        }
                  });
            }

             // Initialize the bean instance.
            Object exposedObject = bean;
             try {
// 所创建的bean需要进行初始化操作,并进行依赖注入的操作,这些操作通过populateBean方法来完成
                  populateBean(beanName, mbd, instanceWrapper);
                   if (exposedObject != null) {
                        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 );
                   if (earlySingletonReference != null) {
                         if (exposedObject == bean) {
                              exposedObject = earlySingletonReference;
                        }
                         else if (!this. allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                              String[] dependentBeans = getDependentBeans(beanName);
                              Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length );
                               for (String dependentBean : dependentBeans) {
                                     if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                                          actualDependentBeans.add(dependentBean);
                                    }
                              }
                               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 " +
                                                 "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                              }
                        }
                  }
            }

             // Register bean as disposable.
             try {
                  registerDisposableBeanIfNecessary(beanName, bean, mbd);
            }
             catch (BeanDefinitionValidationException ex) {
                   throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
            }

             return exposedObject;
      }

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.class
// 具体的创建bean实例,是通过createBeanInstance方法实现的
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
             // Make sure bean class is actually resolved at this point.
            Class beanClass = resolveBeanClass(mbd, beanName);

             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());
            }
// 通过工厂方法来实例化bean
             if (mbd.getFactoryMethodName() != null)  {
                   return instantiateUsingFactoryMethod(beanName, mbd, args);
            }

             // Shortcut when re-creating the same bean...
             boolean resolved = false;
             boolean autowireNecessary = false;
             if (args == null) {
                   synchronized (mbd.constructorArgumentLock ) {
                         if (mbd.resolvedConstructorOrFactoryMethod != null) {
                              resolved = true;
                              autowireNecessary = mbd.constructorArgumentsResolved ;
                        }
                  }
            }
             if (resolved) {
                   if (autowireNecessary) {
                         return autowireConstructor(beanName, mbd, null, null);
                  }
                   else {
                         return instantiateBean(beanName, mbd);
                  }
            }

             // Need to determine the constructor...
// 使用构造函数来实例化bean
            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.
// 使用默认的构造函数来实例化bean
             return instantiateBean(beanName, mbd);
      }

org.springframework.beans.factory.support.SimpleInstantiationStrategy.class
// 具体的实例过程可以使用CGLIB对bean进行实例化,也可以使用JDK的反射进行实例化
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
             // Don't override the class with CGLIB if no overrides.
             if (beanDefinition.getMethodOverrides().isEmpty()) {
                  Constructor<?> constructorToUse;
                   synchronized (beanDefinition.constructorArgumentLock ) {
                        constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod ;
                         if (constructorToUse == null) {
                               final Class clazz = beanDefinition.getBeanClass();
                               if (clazz.isInterface()) {
                                     throw new BeanInstantiationException(clazz, "Specified class is an interface" );
                              }
                               try {
                                     if (System.getSecurityManager() != null) {
                                          constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor>() {
                                                 public Constructor run() throws Exception {
                                                       return clazz.getDeclaredConstructor((Class[]) null);
                                                }
                                          });
                                    }
                                     else {
                                          constructorToUse =      clazz.getDeclaredConstructor((Class[]) null);
                                    }
                                    beanDefinition. resolvedConstructorOrFactoryMethod = constructorToUse;
                              }
                               catch (Exception ex) {
                                     throw new BeanInstantiationException(clazz, "No default constructor found" , ex);
                              }
                        }
                  }
/**
 * instantiateClass方法里使用反射进行实例化的具体实现
 *try {
 *                 ReflectionUtils. makeAccessible(ctor);
 *                  return ctor.newInstance(args);
 *           }
                   return BeanUtils.instantiateClass(constructorToUse);
            }
             else {
                   // Must generate CGLIB subclass.
                   return instantiateWithMethodInjection(beanDefinition, beanName, owner);
            }
      }

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.class
// 完成bean对象的创建,整个注入的过程还没有结束,需要对用户定义的关于bean的各种内部属性进行注入配置
// 具体的注入配置通过populateBean 方法来实现
protected void populateBean (String beanName, AbstractBeanDefinition 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, mbd, bw, newPvs);
                  }

                  pvs = newPvs;
            }

             boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
             boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE );

             if (hasInstAwareBpps || needsDepCheck) {
                  PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw);
                   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, mbd, filteredPds, pvs);
                  }
            }

            applyPropertyValues(beanName, mbd, bw, pvs);
}

// 在IOC容器初始化过程中,构建BeanDefinition中封装了内部属性的值
// 这个过程就是要该内部属性的值设置到已经创建的bean实例中
// 比如内部引用的bean实例的注入,list等集合对象的注入
// 成员变量的属性值的设置等

org.springframework.beans.BeanWrapperImpl.class
// 具体实现对各个属性值的注入的实现方法
private void setPropertyValue (PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {
            String propertyName = tokens. canonicalName;
            String actualName = tokens. actualName;

             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, 0, getterTokens. keys, 0, 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 (this .autoGrowNestedPaths ) {
                               // 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(), this.nestedPath + propertyName,
                                           "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 ));
                              Array. set(propValue, arrayIndex, convertedValue);
                        }
                         catch (IndexOutOfBoundsException ex) {
                               throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
                                           "Invalid array index in property path '" + propertyName + "'", ex);
                        }
                  }
                   else if (propValue instanceof List) {
                        PropertyDescriptor pd = getCachedIntrospectionResults().getPropertyDescriptor(actualName);
                        Class requiredType = GenericCollectionTypeResolver.getCollectionReturnType(
                                    pd.getReadMethod(), tokens.keys.length );
                        List list = (List) propValue;
                         int index = Integer.parseInt(key);
                        Object oldValue = null;
                         if (isExtractOldValueForEditor() && index < list.size()) {
                              oldValue = list.get(index);
                        }
                        Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(),
                                    requiredType, TypeDescriptor.nested(property(pd), 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(), this.nestedPath + propertyName,
                                                       "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.set(index, convertedValue);
                              }
                               catch (IndexOutOfBoundsException ex) {
                                     throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
                                                 "Invalid list index in property path '" + propertyName + "'", ex);
                              }
                        }
                  }
                   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 map = (Map) 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 = (mapKeyType != null ?
                                    TypeDescriptor. valueOf(mapKeyType) : TypeDescriptor.valueOf(Object.class));
                        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, oldValue, pv.getValue(),
                                    mapValueType, TypeDescriptor.nested(property(pd), tokens. keys.length ));
                        map.put(convertedMapKey, convertedMapValue);
                  }
                   else {
                         throw new InvalidPropertyException(getRootClass(), this.nestedPath + propertyName,
                                     "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(), this.nestedPath + propertyName,
                                                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 ) {
                                           final Method readMethod = pd.getReadMethod();
                                           if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers()) &&
                                                      !readMethod.isAccessible()) {
                                                 if (System.getSecurityManager()!= null) {
                                                      AccessController. doPrivileged(new PrivilegedAction<Object>() {
                                                             public Object run() {
                                                                  readMethod.setAccessible( true);
                                                                   return null;
                                                            }
                                                      });
                                                }
                                                 else {
                                                      readMethod.setAccessible( true);
                                                }
                                          }
                                           try {
                                                 if (System.getSecurityManager() != null) {
                                                      oldValue = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
                                                             public Object run() throws Exception {
                                                                   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, oldValue, originalValue, 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>() {
                                           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>() {
                                           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 , this.nestedPath + propertyName, oldValue, 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 , this.nestedPath + propertyName, oldValue, pv.getValue());
                         throw new MethodInvocationException(pce, ex);
                  }
            }
      }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值