Consistent throwing of BeanCreationExceptions (and reflection exceptions)
Issue: SPR-14883
This commit is contained in:
		
							parent
							
								
									fd7045adac
								
							
						
					
					
						commit
						b42d731fc8
					
				| 
						 | 
					@ -220,7 +220,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
 | 
						public void setBeanFactory(BeanFactory beanFactory) {
 | 
				
			||||||
		if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
 | 
							if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
 | 
				
			||||||
			throw new IllegalArgumentException(
 | 
								throw new IllegalArgumentException(
 | 
				
			||||||
					"AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory");
 | 
										"AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory");
 | 
				
			||||||
| 
						 | 
					@ -238,7 +238,10 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName) throws BeansException {
 | 
						public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
 | 
				
			||||||
 | 
								throws BeanCreationException {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Let's check for lookup methods here..
 | 
				
			||||||
		if (!this.lookupMethodsChecked.contains(beanName)) {
 | 
							if (!this.lookupMethodsChecked.contains(beanName)) {
 | 
				
			||||||
			ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() {
 | 
								ReflectionUtils.doWithMethods(beanClass, new ReflectionUtils.MethodCallback() {
 | 
				
			||||||
				@Override
 | 
									@Override
 | 
				
			||||||
| 
						 | 
					@ -263,10 +266,19 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
 | 
				
			||||||
		// Quick check on the concurrent map first, with minimal locking.
 | 
							// Quick check on the concurrent map first, with minimal locking.
 | 
				
			||||||
		Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
 | 
							Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
 | 
				
			||||||
		if (candidateConstructors == null) {
 | 
							if (candidateConstructors == null) {
 | 
				
			||||||
 | 
								// Fully synchronized resolution now...
 | 
				
			||||||
			synchronized (this.candidateConstructorsCache) {
 | 
								synchronized (this.candidateConstructorsCache) {
 | 
				
			||||||
				candidateConstructors = this.candidateConstructorsCache.get(beanClass);
 | 
									candidateConstructors = this.candidateConstructorsCache.get(beanClass);
 | 
				
			||||||
				if (candidateConstructors == null) {
 | 
									if (candidateConstructors == null) {
 | 
				
			||||||
					Constructor<?>[] rawCandidates = beanClass.getDeclaredConstructors();
 | 
										Constructor<?>[] rawCandidates;
 | 
				
			||||||
 | 
										try {
 | 
				
			||||||
 | 
											rawCandidates = beanClass.getDeclaredConstructors();
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										catch (Throwable ex) {
 | 
				
			||||||
 | 
											throw new BeanCreationException(beanName,
 | 
				
			||||||
 | 
													"Resolution of declared constructors on bean Class [" + beanClass.getName() +
 | 
				
			||||||
 | 
													"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
					List<Constructor<?>> candidates = new ArrayList<Constructor<?>>(rawCandidates.length);
 | 
										List<Constructor<?>> candidates = new ArrayList<Constructor<?>>(rawCandidates.length);
 | 
				
			||||||
					Constructor<?> requiredConstructor = null;
 | 
										Constructor<?> requiredConstructor = null;
 | 
				
			||||||
					Constructor<?> defaultConstructor = null;
 | 
										Constructor<?> defaultConstructor = null;
 | 
				
			||||||
| 
						 | 
					@ -320,9 +332,9 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							else if (candidates.size() == 1 && logger.isWarnEnabled()) {
 | 
												else if (candidates.size() == 1 && logger.isWarnEnabled()) {
 | 
				
			||||||
								logger.warn("Inconsistent constructor declaration on bean with name '" + beanName +
 | 
													logger.warn("Inconsistent constructor declaration on bean with name '" + beanName +
 | 
				
			||||||
										"': single autowire-marked constructor flagged as optional - this constructor " +
 | 
															"': single autowire-marked constructor flagged as optional - " +
 | 
				
			||||||
										"is effectively required since there is no default constructor to fall back to: " +
 | 
															"this constructor is effectively required since there is no " +
 | 
				
			||||||
										candidates.get(0));
 | 
															"default constructor to fall back to: " + candidates.get(0));
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						candidateConstructors = candidates.toArray(new Constructor<?>[candidates.size()]);
 | 
											candidateConstructors = candidates.toArray(new Constructor<?>[candidates.size()]);
 | 
				
			||||||
| 
						 | 
					@ -342,7 +354,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public PropertyValues postProcessPropertyValues(
 | 
						public PropertyValues postProcessPropertyValues(
 | 
				
			||||||
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
 | 
								PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
 | 
							InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
| 
						 | 
					@ -361,9 +373,9 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
 | 
				
			||||||
	 * 'Native' processing method for direct calls with an arbitrary target instance,
 | 
						 * 'Native' processing method for direct calls with an arbitrary target instance,
 | 
				
			||||||
	 * resolving all of its fields and methods which are annotated with {@code @Autowired}.
 | 
						 * resolving all of its fields and methods which are annotated with {@code @Autowired}.
 | 
				
			||||||
	 * @param bean the target instance to process
 | 
						 * @param bean the target instance to process
 | 
				
			||||||
	 * @throws BeansException if autowiring failed
 | 
						 * @throws BeanCreationException if autowiring failed
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public void processInjection(Object bean) throws BeansException {
 | 
						public void processInjection(Object bean) throws BeanCreationException {
 | 
				
			||||||
		Class<?> clazz = bean.getClass();
 | 
							Class<?> clazz = bean.getClass();
 | 
				
			||||||
		InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz, null);
 | 
							InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz, null);
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
| 
						 | 
					@ -373,7 +385,8 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
 | 
				
			||||||
			throw ex;
 | 
								throw ex;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		catch (Throwable ex) {
 | 
							catch (Throwable ex) {
 | 
				
			||||||
			throw new BeanCreationException("Injection of autowired dependencies failed for class [" + clazz + "]", ex);
 | 
								throw new BeanCreationException(
 | 
				
			||||||
 | 
										"Injection of autowired dependencies failed for class [" + clazz + "]", ex);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -446,7 +459,8 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						if (method.getParameterTypes().length == 0) {
 | 
											if (method.getParameterTypes().length == 0) {
 | 
				
			||||||
							if (logger.isWarnEnabled()) {
 | 
												if (logger.isWarnEnabled()) {
 | 
				
			||||||
								logger.warn("Autowired annotation should be used on methods with parameters: " + method);
 | 
													logger.warn("Autowired annotation should only be used on methods with parameters: " +
 | 
				
			||||||
 | 
															method);
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						boolean required = determineRequiredStatus(ann);
 | 
											boolean required = determineRequiredStatus(ann);
 | 
				
			||||||
| 
						 | 
					@ -629,7 +643,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
 | 
				
			||||||
				Class<?>[] paramTypes = method.getParameterTypes();
 | 
									Class<?>[] paramTypes = method.getParameterTypes();
 | 
				
			||||||
				arguments = new Object[paramTypes.length];
 | 
									arguments = new Object[paramTypes.length];
 | 
				
			||||||
				DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length];
 | 
									DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length];
 | 
				
			||||||
				Set<String> autowiredBeanNames = new LinkedHashSet<String>(paramTypes.length);
 | 
									Set<String> autowiredBeans = new LinkedHashSet<String>(paramTypes.length);
 | 
				
			||||||
				TypeConverter typeConverter = beanFactory.getTypeConverter();
 | 
									TypeConverter typeConverter = beanFactory.getTypeConverter();
 | 
				
			||||||
				for (int i = 0; i < arguments.length; i++) {
 | 
									for (int i = 0; i < arguments.length; i++) {
 | 
				
			||||||
					MethodParameter methodParam = new MethodParameter(method, i);
 | 
										MethodParameter methodParam = new MethodParameter(method, i);
 | 
				
			||||||
| 
						 | 
					@ -637,7 +651,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
 | 
				
			||||||
					currDesc.setContainingClass(bean.getClass());
 | 
										currDesc.setContainingClass(bean.getClass());
 | 
				
			||||||
					descriptors[i] = currDesc;
 | 
										descriptors[i] = currDesc;
 | 
				
			||||||
					try {
 | 
										try {
 | 
				
			||||||
						Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeanNames, typeConverter);
 | 
											Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
 | 
				
			||||||
						if (arg == null && !this.required) {
 | 
											if (arg == null && !this.required) {
 | 
				
			||||||
							arguments = null;
 | 
												arguments = null;
 | 
				
			||||||
							break;
 | 
												break;
 | 
				
			||||||
| 
						 | 
					@ -655,9 +669,9 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
 | 
				
			||||||
							for (int i = 0; i < arguments.length; i++) {
 | 
												for (int i = 0; i < arguments.length; i++) {
 | 
				
			||||||
								this.cachedMethodArguments[i] = descriptors[i];
 | 
													this.cachedMethodArguments[i] = descriptors[i];
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							registerDependentBeans(beanName, autowiredBeanNames);
 | 
												registerDependentBeans(beanName, autowiredBeans);
 | 
				
			||||||
							if (autowiredBeanNames.size() == paramTypes.length) {
 | 
												if (autowiredBeans.size() == paramTypes.length) {
 | 
				
			||||||
								Iterator<String> it = autowiredBeanNames.iterator();
 | 
													Iterator<String> it = autowiredBeans.iterator();
 | 
				
			||||||
								for (int i = 0; i < paramTypes.length; i++) {
 | 
													for (int i = 0; i < paramTypes.length; i++) {
 | 
				
			||||||
									String autowiredBeanName = it.next();
 | 
														String autowiredBeanName = it.next();
 | 
				
			||||||
									if (beanFactory.containsBean(autowiredBeanName)) {
 | 
														if (beanFactory.containsBean(autowiredBeanName)) {
 | 
				
			||||||
| 
						 | 
					@ -706,19 +720,19 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
 | 
				
			||||||
	@SuppressWarnings("serial")
 | 
						@SuppressWarnings("serial")
 | 
				
			||||||
	private static class ShortcutDependencyDescriptor extends DependencyDescriptor {
 | 
						private static class ShortcutDependencyDescriptor extends DependencyDescriptor {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private final String shortcutName;
 | 
							private final String shortcut;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private final Class<?> requiredType;
 | 
							private final Class<?> requiredType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public ShortcutDependencyDescriptor(DependencyDescriptor original, String shortcutName, Class<?> requiredType) {
 | 
							public ShortcutDependencyDescriptor(DependencyDescriptor original, String shortcut, Class<?> requiredType) {
 | 
				
			||||||
			super(original);
 | 
								super(original);
 | 
				
			||||||
			this.shortcutName = shortcutName;
 | 
								this.shortcut = shortcut;
 | 
				
			||||||
			this.requiredType = requiredType;
 | 
								this.requiredType = requiredType;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		@Override
 | 
							@Override
 | 
				
			||||||
		public Object resolveShortcut(BeanFactory beanFactory) {
 | 
							public Object resolveShortcut(BeanFactory beanFactory) {
 | 
				
			||||||
			return resolveCandidate(this.shortcutName, this.requiredType, beanFactory);
 | 
								return resolveCandidate(this.shortcut, this.requiredType, beanFactory);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2002-2013 the original author or authors.
 | 
					 * Copyright 2002-2016 the original author or authors.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 * you may not use this file except in compliance with the License.
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
| 
						 | 
					@ -141,8 +141,7 @@ public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanP
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public PropertyValues postProcessPropertyValues(
 | 
						public PropertyValues postProcessPropertyValues(
 | 
				
			||||||
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
 | 
								PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
 | 
				
			||||||
			throws BeansException {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!this.validatedBeanNames.contains(beanName)) {
 | 
							if (!this.validatedBeanNames.contains(beanName)) {
 | 
				
			||||||
			if (!shouldSkip(this.beanFactory, beanName)) {
 | 
								if (!shouldSkip(this.beanFactory, beanName)) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,5 @@
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Copyright 2002-2012 the original author or authors.
 | 
					 * Copyright 2002-2016 the original author or authors.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
				
			||||||
 * you may not use this file except in compliance with the License.
 | 
					 * you may not use this file except in compliance with the License.
 | 
				
			||||||
| 
						 | 
					@ -66,8 +66,7 @@ public abstract class InstantiationAwareBeanPostProcessorAdapter implements Smar
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public PropertyValues postProcessPropertyValues(
 | 
						public PropertyValues postProcessPropertyValues(
 | 
				
			||||||
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
 | 
								PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
 | 
				
			||||||
			throws BeansException {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return pvs;
 | 
							return pvs;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -479,12 +479,22 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
 | 
				
			||||||
					"BeanPostProcessor before instantiation of bean failed", ex);
 | 
										"BeanPostProcessor before instantiation of bean failed", ex);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							try {
 | 
				
			||||||
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
 | 
								Object beanInstance = doCreateBean(beanName, mbdToUse, args);
 | 
				
			||||||
			if (logger.isDebugEnabled()) {
 | 
								if (logger.isDebugEnabled()) {
 | 
				
			||||||
				logger.debug("Finished creating instance of bean '" + beanName + "'");
 | 
									logger.debug("Finished creating instance of bean '" + beanName + "'");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return beanInstance;
 | 
								return beanInstance;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							catch (BeanCreationException ex) {
 | 
				
			||||||
 | 
								// A previously detected exception with proper bean creation context already...
 | 
				
			||||||
 | 
								throw ex;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							catch (Throwable ex) {
 | 
				
			||||||
 | 
								throw new BeanCreationException(
 | 
				
			||||||
 | 
										mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Actually create the specified bean. Pre-creation processing has already happened
 | 
						 * Actually create the specified bean. Pre-creation processing has already happened
 | 
				
			||||||
| 
						 | 
					@ -500,7 +510,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
 | 
				
			||||||
	 * @see #instantiateUsingFactoryMethod
 | 
						 * @see #instantiateUsingFactoryMethod
 | 
				
			||||||
	 * @see #autowireConstructor
 | 
						 * @see #autowireConstructor
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
 | 
						protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
 | 
				
			||||||
 | 
								throws BeanCreationException {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Instantiate the bean.
 | 
							// Instantiate the bean.
 | 
				
			||||||
		BeanWrapper instanceWrapper = null;
 | 
							BeanWrapper instanceWrapper = null;
 | 
				
			||||||
		if (mbd.isSingleton()) {
 | 
							if (mbd.isSingleton()) {
 | 
				
			||||||
| 
						 | 
					@ -515,7 +527,13 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
 | 
				
			||||||
		// Allow post-processors to modify the merged bean definition.
 | 
							// Allow post-processors to modify the merged bean definition.
 | 
				
			||||||
		synchronized (mbd.postProcessingLock) {
 | 
							synchronized (mbd.postProcessingLock) {
 | 
				
			||||||
			if (!mbd.postProcessed) {
 | 
								if (!mbd.postProcessed) {
 | 
				
			||||||
 | 
									try {
 | 
				
			||||||
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
 | 
										applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									catch (Throwable ex) {
 | 
				
			||||||
 | 
										throw new BeanCreationException(mbd.getResourceDescription(), beanName,
 | 
				
			||||||
 | 
												"Post-processing failed of bean type [" + beanType + "] failed", ex);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				mbd.postProcessed = true;
 | 
									mbd.postProcessed = true;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -550,7 +568,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
 | 
				
			||||||
				throw (BeanCreationException) ex;
 | 
									throw (BeanCreationException) ex;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else {
 | 
								else {
 | 
				
			||||||
				throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
 | 
									throw new BeanCreationException(
 | 
				
			||||||
 | 
											mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -586,7 +605,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
 | 
				
			||||||
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
 | 
								registerDisposableBeanIfNecessary(beanName, bean, mbd);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		catch (BeanDefinitionValidationException ex) {
 | 
							catch (BeanDefinitionValidationException ex) {
 | 
				
			||||||
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
 | 
								throw new BeanCreationException(
 | 
				
			||||||
 | 
										mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return exposedObject;
 | 
							return exposedObject;
 | 
				
			||||||
| 
						 | 
					@ -773,10 +793,11 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
 | 
				
			||||||
					ReflectionUtils.doWithMethods(fbClass,
 | 
										ReflectionUtils.doWithMethods(fbClass,
 | 
				
			||||||
							new ReflectionUtils.MethodCallback() {
 | 
												new ReflectionUtils.MethodCallback() {
 | 
				
			||||||
								@Override
 | 
													@Override
 | 
				
			||||||
								public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
 | 
													public void doWith(Method method) {
 | 
				
			||||||
									if (method.getName().equals(factoryMethodName) &&
 | 
														if (method.getName().equals(factoryMethodName) &&
 | 
				
			||||||
											FactoryBean.class.isAssignableFrom(method.getReturnType())) {
 | 
																FactoryBean.class.isAssignableFrom(method.getReturnType())) {
 | 
				
			||||||
										objectType.value = GenericTypeResolver.resolveReturnTypeArgument(method, FactoryBean.class);
 | 
															objectType.value = GenericTypeResolver.resolveReturnTypeArgument(
 | 
				
			||||||
 | 
																	method, FactoryBean.class);
 | 
				
			||||||
									}
 | 
														}
 | 
				
			||||||
								}
 | 
													}
 | 
				
			||||||
							});
 | 
												});
 | 
				
			||||||
| 
						 | 
					@ -933,7 +954,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
 | 
				
			||||||
	protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName)
 | 
						protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName)
 | 
				
			||||||
			throws BeansException {
 | 
								throws BeansException {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		try {
 | 
					 | 
				
			||||||
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
 | 
							for (BeanPostProcessor bp : getBeanPostProcessors()) {
 | 
				
			||||||
			if (bp instanceof MergedBeanDefinitionPostProcessor) {
 | 
								if (bp instanceof MergedBeanDefinitionPostProcessor) {
 | 
				
			||||||
				MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
 | 
									MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
 | 
				
			||||||
| 
						 | 
					@ -941,11 +961,6 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		catch (Exception ex) {
 | 
					 | 
				
			||||||
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
 | 
					 | 
				
			||||||
					"Post-processing failed of bean type [" + beanType + "] failed", ex);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Apply before-instantiation post-processors, resolving whether there is a
 | 
						 * Apply before-instantiation post-processors, resolving whether there is a
 | 
				
			||||||
| 
						 | 
					@ -1107,7 +1122,8 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
 | 
				
			||||||
			return bw;
 | 
								return bw;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		catch (Throwable ex) {
 | 
							catch (Throwable ex) {
 | 
				
			||||||
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
 | 
								throw new BeanCreationException(
 | 
				
			||||||
 | 
										mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1659,7 +1675,9 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
 | 
				
			||||||
	 * methods with arguments.
 | 
						 * methods with arguments.
 | 
				
			||||||
	 * @see #invokeInitMethods
 | 
						 * @see #invokeInitMethods
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {
 | 
						protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd)
 | 
				
			||||||
 | 
								throws Throwable {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		String initMethodName = mbd.getInitMethodName();
 | 
							String initMethodName = mbd.getInitMethodName();
 | 
				
			||||||
		final Method initMethod = (mbd.isNonPublicAccessAllowed() ?
 | 
							final Method initMethod = (mbd.isNonPublicAccessAllowed() ?
 | 
				
			||||||
				BeanUtils.findMethod(bean.getClass(), initMethodName) :
 | 
									BeanUtils.findMethod(bean.getClass(), initMethodName) :
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -287,13 +287,13 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
 | 
				
			||||||
				// Guarantee initialization of beans that the current bean depends on.
 | 
									// Guarantee initialization of beans that the current bean depends on.
 | 
				
			||||||
				String[] dependsOn = mbd.getDependsOn();
 | 
									String[] dependsOn = mbd.getDependsOn();
 | 
				
			||||||
				if (dependsOn != null) {
 | 
									if (dependsOn != null) {
 | 
				
			||||||
					for (String dependsOnBean : dependsOn) {
 | 
										for (String dep : dependsOn) {
 | 
				
			||||||
						if (isDependent(beanName, dependsOnBean)) {
 | 
											if (isDependent(beanName, dep)) {
 | 
				
			||||||
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
 | 
												throw new BeanCreationException(mbd.getResourceDescription(), beanName,
 | 
				
			||||||
									"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
 | 
														"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						registerDependentBean(dependsOnBean, beanName);
 | 
											registerDependentBean(dep, beanName);
 | 
				
			||||||
						getBean(dependsOnBean);
 | 
											getBean(dep);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -460,19 +460,19 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
 | 
				
			||||||
				return false;
 | 
									return false;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (isFactoryBean(beanName, mbd)) {
 | 
								if (isFactoryBean(beanName, mbd)) {
 | 
				
			||||||
				final FactoryBean<?> factoryBean = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
 | 
									final FactoryBean<?> fb = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
 | 
				
			||||||
				if (System.getSecurityManager() != null) {
 | 
									if (System.getSecurityManager() != null) {
 | 
				
			||||||
					return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
 | 
										return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
 | 
				
			||||||
						@Override
 | 
											@Override
 | 
				
			||||||
						public Boolean run() {
 | 
											public Boolean run() {
 | 
				
			||||||
							return ((factoryBean instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factoryBean).isPrototype()) ||
 | 
												return ((fb instanceof SmartFactoryBean && ((SmartFactoryBean<?>) fb).isPrototype()) ||
 | 
				
			||||||
									!factoryBean.isSingleton());
 | 
														!fb.isSingleton());
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}, getAccessControlContext());
 | 
										}, getAccessControlContext());
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				else {
 | 
									else {
 | 
				
			||||||
					return ((factoryBean instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factoryBean).isPrototype()) ||
 | 
										return ((fb instanceof SmartFactoryBean && ((SmartFactoryBean<?>) fb).isPrototype()) ||
 | 
				
			||||||
							!factoryBean.isSingleton());
 | 
												!fb.isSingleton());
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else {
 | 
								else {
 | 
				
			||||||
| 
						 | 
					@ -1053,11 +1053,11 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
 | 
				
			||||||
	 * Destroy the given bean instance (usually a prototype instance
 | 
						 * Destroy the given bean instance (usually a prototype instance
 | 
				
			||||||
	 * obtained from this factory) according to the given bean definition.
 | 
						 * obtained from this factory) according to the given bean definition.
 | 
				
			||||||
	 * @param beanName the name of the bean definition
 | 
						 * @param beanName the name of the bean definition
 | 
				
			||||||
	 * @param beanInstance the bean instance to destroy
 | 
						 * @param bean the bean instance to destroy
 | 
				
			||||||
	 * @param mbd the merged bean definition
 | 
						 * @param mbd the merged bean definition
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	protected void destroyBean(String beanName, Object beanInstance, RootBeanDefinition mbd) {
 | 
						protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) {
 | 
				
			||||||
		new DisposableBeanAdapter(beanInstance, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy();
 | 
							new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
| 
						 | 
					@ -1238,12 +1238,13 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
 | 
				
			||||||
							pbd = getMergedBeanDefinition(parentBeanName);
 | 
												pbd = getMergedBeanDefinition(parentBeanName);
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						else {
 | 
											else {
 | 
				
			||||||
							if (getParentBeanFactory() instanceof ConfigurableBeanFactory) {
 | 
												BeanFactory parent = getParentBeanFactory();
 | 
				
			||||||
								pbd = ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(parentBeanName);
 | 
												if (parent instanceof ConfigurableBeanFactory) {
 | 
				
			||||||
 | 
													pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							else {
 | 
												else {
 | 
				
			||||||
								throw new NoSuchBeanDefinitionException(bd.getParentName(),
 | 
													throw new NoSuchBeanDefinitionException(parentBeanName,
 | 
				
			||||||
										"Parent name '" + bd.getParentName() + "' is equal to bean name '" + beanName +
 | 
															"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
 | 
				
			||||||
										"': cannot be resolved without an AbstractBeanFactory parent");
 | 
															"': cannot be resolved without an AbstractBeanFactory parent");
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
| 
						 | 
					@ -1359,12 +1360,14 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
 | 
				
			||||||
		catch (ClassNotFoundException ex) {
 | 
							catch (ClassNotFoundException ex) {
 | 
				
			||||||
			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
 | 
								throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		catch (LinkageError err) {
 | 
							catch (LinkageError ex) {
 | 
				
			||||||
			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
 | 
								throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch) throws ClassNotFoundException {
 | 
						private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
 | 
				
			||||||
 | 
								throws ClassNotFoundException {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ClassLoader beanClassLoader = getBeanClassLoader();
 | 
							ClassLoader beanClassLoader = getBeanClassLoader();
 | 
				
			||||||
		ClassLoader classLoaderToUse = beanClassLoader;
 | 
							ClassLoader classLoaderToUse = beanClassLoader;
 | 
				
			||||||
		if (!ObjectUtils.isEmpty(typesToMatch)) {
 | 
							if (!ObjectUtils.isEmpty(typesToMatch)) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -483,6 +483,7 @@ public abstract class ReflectionUtils {
 | 
				
			||||||
	 * @param clazz the class to introspect
 | 
						 * @param clazz the class to introspect
 | 
				
			||||||
	 * @param mc the callback to invoke for each method
 | 
						 * @param mc the callback to invoke for each method
 | 
				
			||||||
	 * @since 4.2
 | 
						 * @since 4.2
 | 
				
			||||||
 | 
						 * @throws IllegalStateException if introspection fails
 | 
				
			||||||
	 * @see #doWithMethods
 | 
						 * @see #doWithMethods
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public static void doWithLocalMethods(Class<?> clazz, MethodCallback mc) {
 | 
						public static void doWithLocalMethods(Class<?> clazz, MethodCallback mc) {
 | 
				
			||||||
| 
						 | 
					@ -504,6 +505,7 @@ public abstract class ReflectionUtils {
 | 
				
			||||||
	 * twice, unless excluded by a {@link MethodFilter}.
 | 
						 * twice, unless excluded by a {@link MethodFilter}.
 | 
				
			||||||
	 * @param clazz the class to introspect
 | 
						 * @param clazz the class to introspect
 | 
				
			||||||
	 * @param mc the callback to invoke for each method
 | 
						 * @param mc the callback to invoke for each method
 | 
				
			||||||
 | 
						 * @throws IllegalStateException if introspection fails
 | 
				
			||||||
	 * @see #doWithMethods(Class, MethodCallback, MethodFilter)
 | 
						 * @see #doWithMethods(Class, MethodCallback, MethodFilter)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public static void doWithMethods(Class<?> clazz, MethodCallback mc) {
 | 
						public static void doWithMethods(Class<?> clazz, MethodCallback mc) {
 | 
				
			||||||
| 
						 | 
					@ -518,6 +520,7 @@ public abstract class ReflectionUtils {
 | 
				
			||||||
	 * @param clazz the class to introspect
 | 
						 * @param clazz the class to introspect
 | 
				
			||||||
	 * @param mc the callback to invoke for each method
 | 
						 * @param mc the callback to invoke for each method
 | 
				
			||||||
	 * @param mf the filter that determines the methods to apply the callback to
 | 
						 * @param mf the filter that determines the methods to apply the callback to
 | 
				
			||||||
 | 
						 * @throws IllegalStateException if introspection fails
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public static void doWithMethods(Class<?> clazz, MethodCallback mc, MethodFilter mf) {
 | 
						public static void doWithMethods(Class<?> clazz, MethodCallback mc, MethodFilter mf) {
 | 
				
			||||||
		// Keep backing up the inheritance hierarchy.
 | 
							// Keep backing up the inheritance hierarchy.
 | 
				
			||||||
| 
						 | 
					@ -547,6 +550,7 @@ public abstract class ReflectionUtils {
 | 
				
			||||||
	 * Get all declared methods on the leaf class and all superclasses.
 | 
						 * Get all declared methods on the leaf class and all superclasses.
 | 
				
			||||||
	 * Leaf class methods are included first.
 | 
						 * Leaf class methods are included first.
 | 
				
			||||||
	 * @param leafClass the class to introspect
 | 
						 * @param leafClass the class to introspect
 | 
				
			||||||
 | 
						 * @throws IllegalStateException if introspection fails
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public static Method[] getAllDeclaredMethods(Class<?> leafClass) {
 | 
						public static Method[] getAllDeclaredMethods(Class<?> leafClass) {
 | 
				
			||||||
		final List<Method> methods = new ArrayList<Method>(32);
 | 
							final List<Method> methods = new ArrayList<Method>(32);
 | 
				
			||||||
| 
						 | 
					@ -564,6 +568,7 @@ public abstract class ReflectionUtils {
 | 
				
			||||||
	 * Leaf class methods are included first and while traversing the superclass hierarchy
 | 
						 * Leaf class methods are included first and while traversing the superclass hierarchy
 | 
				
			||||||
	 * any methods found with signatures matching a method already included are filtered out.
 | 
						 * any methods found with signatures matching a method already included are filtered out.
 | 
				
			||||||
	 * @param leafClass the class to introspect
 | 
						 * @param leafClass the class to introspect
 | 
				
			||||||
 | 
						 * @throws IllegalStateException if introspection fails
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public static Method[] getUniqueDeclaredMethods(Class<?> leafClass) {
 | 
						public static Method[] getUniqueDeclaredMethods(Class<?> leafClass) {
 | 
				
			||||||
		final List<Method> methods = new ArrayList<Method>(32);
 | 
							final List<Method> methods = new ArrayList<Method>(32);
 | 
				
			||||||
| 
						 | 
					@ -604,11 +609,13 @@ public abstract class ReflectionUtils {
 | 
				
			||||||
	 * interfaces, since those are effectively to be treated just like declared methods.
 | 
						 * interfaces, since those are effectively to be treated just like declared methods.
 | 
				
			||||||
	 * @param clazz the class to introspect
 | 
						 * @param clazz the class to introspect
 | 
				
			||||||
	 * @return the cached array of methods
 | 
						 * @return the cached array of methods
 | 
				
			||||||
 | 
						 * @throws IllegalStateException if introspection fails
 | 
				
			||||||
	 * @see Class#getDeclaredMethods()
 | 
						 * @see Class#getDeclaredMethods()
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	private static Method[] getDeclaredMethods(Class<?> clazz) {
 | 
						private static Method[] getDeclaredMethods(Class<?> clazz) {
 | 
				
			||||||
		Method[] result = declaredMethodsCache.get(clazz);
 | 
							Method[] result = declaredMethodsCache.get(clazz);
 | 
				
			||||||
		if (result == null) {
 | 
							if (result == null) {
 | 
				
			||||||
 | 
								try {
 | 
				
			||||||
				Method[] declaredMethods = clazz.getDeclaredMethods();
 | 
									Method[] declaredMethods = clazz.getDeclaredMethods();
 | 
				
			||||||
				List<Method> defaultMethods = findConcreteMethodsOnInterfaces(clazz);
 | 
									List<Method> defaultMethods = findConcreteMethodsOnInterfaces(clazz);
 | 
				
			||||||
				if (defaultMethods != null) {
 | 
									if (defaultMethods != null) {
 | 
				
			||||||
| 
						 | 
					@ -625,6 +632,11 @@ public abstract class ReflectionUtils {
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				declaredMethodsCache.put(clazz, (result.length == 0 ? NO_METHODS : result));
 | 
									declaredMethodsCache.put(clazz, (result.length == 0 ? NO_METHODS : result));
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								catch (Throwable ex) {
 | 
				
			||||||
 | 
									throw new IllegalStateException("Failed to introspect Class [" + clazz +
 | 
				
			||||||
 | 
											"] from ClassLoader [" + clazz.getClassLoader() + "]", ex);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return result;
 | 
							return result;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -649,6 +661,7 @@ public abstract class ReflectionUtils {
 | 
				
			||||||
	 * @param clazz the target class to analyze
 | 
						 * @param clazz the target class to analyze
 | 
				
			||||||
	 * @param fc the callback to invoke for each field
 | 
						 * @param fc the callback to invoke for each field
 | 
				
			||||||
	 * @since 4.2
 | 
						 * @since 4.2
 | 
				
			||||||
 | 
						 * @throws IllegalStateException if introspection fails
 | 
				
			||||||
	 * @see #doWithFields
 | 
						 * @see #doWithFields
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public static void doWithLocalFields(Class<?> clazz, FieldCallback fc) {
 | 
						public static void doWithLocalFields(Class<?> clazz, FieldCallback fc) {
 | 
				
			||||||
| 
						 | 
					@ -667,6 +680,7 @@ public abstract class ReflectionUtils {
 | 
				
			||||||
	 * class hierarchy to get all declared fields.
 | 
						 * class hierarchy to get all declared fields.
 | 
				
			||||||
	 * @param clazz the target class to analyze
 | 
						 * @param clazz the target class to analyze
 | 
				
			||||||
	 * @param fc the callback to invoke for each field
 | 
						 * @param fc the callback to invoke for each field
 | 
				
			||||||
 | 
						 * @throws IllegalStateException if introspection fails
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public static void doWithFields(Class<?> clazz, FieldCallback fc) {
 | 
						public static void doWithFields(Class<?> clazz, FieldCallback fc) {
 | 
				
			||||||
		doWithFields(clazz, fc, null);
 | 
							doWithFields(clazz, fc, null);
 | 
				
			||||||
| 
						 | 
					@ -678,6 +692,7 @@ public abstract class ReflectionUtils {
 | 
				
			||||||
	 * @param clazz the target class to analyze
 | 
						 * @param clazz the target class to analyze
 | 
				
			||||||
	 * @param fc the callback to invoke for each field
 | 
						 * @param fc the callback to invoke for each field
 | 
				
			||||||
	 * @param ff the filter that determines the fields to apply the callback to
 | 
						 * @param ff the filter that determines the fields to apply the callback to
 | 
				
			||||||
 | 
						 * @throws IllegalStateException if introspection fails
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public static void doWithFields(Class<?> clazz, FieldCallback fc, FieldFilter ff) {
 | 
						public static void doWithFields(Class<?> clazz, FieldCallback fc, FieldFilter ff) {
 | 
				
			||||||
		// Keep backing up the inheritance hierarchy.
 | 
							// Keep backing up the inheritance hierarchy.
 | 
				
			||||||
| 
						 | 
					@ -705,14 +720,21 @@ public abstract class ReflectionUtils {
 | 
				
			||||||
	 * in order to avoid the JVM's SecurityManager check and defensive array copying.
 | 
						 * in order to avoid the JVM's SecurityManager check and defensive array copying.
 | 
				
			||||||
	 * @param clazz the class to introspect
 | 
						 * @param clazz the class to introspect
 | 
				
			||||||
	 * @return the cached array of fields
 | 
						 * @return the cached array of fields
 | 
				
			||||||
 | 
						 * @throws IllegalStateException if introspection fails
 | 
				
			||||||
	 * @see Class#getDeclaredFields()
 | 
						 * @see Class#getDeclaredFields()
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	private static Field[] getDeclaredFields(Class<?> clazz) {
 | 
						private static Field[] getDeclaredFields(Class<?> clazz) {
 | 
				
			||||||
		Field[] result = declaredFieldsCache.get(clazz);
 | 
							Field[] result = declaredFieldsCache.get(clazz);
 | 
				
			||||||
		if (result == null) {
 | 
							if (result == null) {
 | 
				
			||||||
 | 
								try {
 | 
				
			||||||
				result = clazz.getDeclaredFields();
 | 
									result = clazz.getDeclaredFields();
 | 
				
			||||||
				declaredFieldsCache.put(clazz, (result.length == 0 ? NO_FIELDS : result));
 | 
									declaredFieldsCache.put(clazz, (result.length == 0 ? NO_FIELDS : result));
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								catch (Throwable ex) {
 | 
				
			||||||
 | 
									throw new IllegalStateException("Failed to introspect Class [" + clazz +
 | 
				
			||||||
 | 
											"] from ClassLoader [" + clazz.getClassLoader() + "]", ex);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return result;
 | 
							return result;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -720,6 +742,7 @@ public abstract class ReflectionUtils {
 | 
				
			||||||
	 * Given the source object and the destination, which must be the same class
 | 
						 * Given the source object and the destination, which must be the same class
 | 
				
			||||||
	 * or a subclass, copy all fields, including inherited fields. Designed to
 | 
						 * or a subclass, copy all fields, including inherited fields. Designed to
 | 
				
			||||||
	 * work on objects with public no-arg constructors.
 | 
						 * work on objects with public no-arg constructors.
 | 
				
			||||||
 | 
						 * @throws IllegalStateException if introspection fails
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	public static void shallowCopyFieldState(final Object src, final Object dest) {
 | 
						public static void shallowCopyFieldState(final Object src, final Object dest) {
 | 
				
			||||||
		if (src == null) {
 | 
							if (src == null) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue