@@ -216,7 +216,7 @@ public int getOrder() {
216216 }
217217
218218 @ Override
219- public void setBeanFactory (BeanFactory beanFactory ) throws BeansException {
219+ public void setBeanFactory (BeanFactory beanFactory ) {
220220 if (!(beanFactory instanceof ConfigurableListableBeanFactory )) {
221221 throw new IllegalArgumentException (
222222 "AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory" );
@@ -234,36 +234,53 @@ public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, C
234234 }
235235
236236 @ Override
237- public Constructor <?>[] determineCandidateConstructors (Class <?> beanClass , final String beanName ) throws BeansException {
237+ public Constructor <?>[] determineCandidateConstructors (Class <?> beanClass , final String beanName )
238+ throws BeanCreationException {
239+
240+ // Let's check for lookup methods here..
238241 if (!this .lookupMethodsChecked .contains (beanName )) {
239- ReflectionUtils .doWithMethods (beanClass , new ReflectionUtils .MethodCallback () {
240- @ Override
241- public void doWith (Method method ) throws IllegalArgumentException , IllegalAccessException {
242- Lookup lookup = method .getAnnotation (Lookup .class );
243- if (lookup != null ) {
244- LookupOverride override = new LookupOverride (method , lookup .value ());
245- try {
246- RootBeanDefinition mbd = (RootBeanDefinition ) beanFactory .getMergedBeanDefinition (beanName );
247- mbd .getMethodOverrides ().addOverride (override );
248- }
249- catch (NoSuchBeanDefinitionException ex ) {
250- throw new BeanCreationException (beanName ,
251- "Cannot apply @Lookup to beans without corresponding bean definition" );
242+ try {
243+ ReflectionUtils .doWithMethods (beanClass , new ReflectionUtils .MethodCallback () {
244+ @ Override
245+ public void doWith (Method method ) throws IllegalArgumentException , IllegalAccessException {
246+ Lookup lookup = method .getAnnotation (Lookup .class );
247+ if (lookup != null ) {
248+ LookupOverride override = new LookupOverride (method , lookup .value ());
249+ try {
250+ RootBeanDefinition mbd = (RootBeanDefinition ) beanFactory .getMergedBeanDefinition (beanName );
251+ mbd .getMethodOverrides ().addOverride (override );
252+ }
253+ catch (NoSuchBeanDefinitionException ex ) {
254+ throw new BeanCreationException (beanName ,
255+ "Cannot apply @Lookup to beans without corresponding bean definition" );
256+ }
252257 }
253258 }
254- }
255- });
259+ });
260+ }
261+ catch (IllegalStateException ex ) {
262+ throw new BeanCreationException (beanName , "Lookup method resolution failed" , ex );
263+ }
256264 this .lookupMethodsChecked .add (beanName );
257265 }
258266
259267 // Quick check on the concurrent map first, with minimal locking.
260268 Constructor <?>[] candidateConstructors = this .candidateConstructorsCache .get (beanClass );
261269 if (candidateConstructors == null ) {
270+ // Fully synchronized resolution now...
262271 synchronized (this .candidateConstructorsCache ) {
263272 candidateConstructors = this .candidateConstructorsCache .get (beanClass );
264273 if (candidateConstructors == null ) {
265- Constructor <?>[] rawCandidates = beanClass .getDeclaredConstructors ();
266- List <Constructor <?>> candidates = new ArrayList <>(rawCandidates .length );
274+ Constructor <?>[] rawCandidates ;
275+ try {
276+ rawCandidates = beanClass .getDeclaredConstructors ();
277+ }
278+ catch (Throwable ex ) {
279+ throw new BeanCreationException (beanName ,
280+ "Resolution of declared constructors on bean Class [" + beanClass .getName () +
281+ "] from ClassLoader [" + beanClass .getClassLoader () + "] failed" , ex );
282+ }
283+ List <Constructor <?>> candidates = new ArrayList <Constructor <?>>(rawCandidates .length );
267284 Constructor <?> requiredConstructor = null ;
268285 Constructor <?> defaultConstructor = null ;
269286 for (Constructor <?> candidate : rawCandidates ) {
@@ -316,9 +333,9 @@ else if (candidate.getParameterCount() == 0) {
316333 }
317334 else if (candidates .size () == 1 && logger .isWarnEnabled ()) {
318335 logger .warn ("Inconsistent constructor declaration on bean with name '" + beanName +
319- "': single autowire-marked constructor flagged as optional - this constructor " +
320- "is effectively required since there is no default constructor to fall back to: " +
321- candidates .get (0 ));
336+ "': single autowire-marked constructor flagged as optional - " +
337+ "this constructor is effectively required since there is no " +
338+ "default constructor to fall back to: " + candidates .get (0 ));
322339 }
323340 }
324341 candidateConstructors = candidates .toArray (new Constructor <?>[candidates .size ()]);
@@ -357,9 +374,9 @@ public PropertyValues postProcessPropertyValues(
357374 * 'Native' processing method for direct calls with an arbitrary target instance,
358375 * resolving all of its fields and methods which are annotated with {@code @Autowired}.
359376 * @param bean the target instance to process
360- * @throws BeansException if autowiring failed
377+ * @throws BeanCreationException if autowiring failed
361378 */
362- public void processInjection (Object bean ) throws BeansException {
379+ public void processInjection (Object bean ) throws BeanCreationException {
363380 Class <?> clazz = bean .getClass ();
364381 InjectionMetadata metadata = findAutowiringMetadata (clazz .getName (), clazz , null );
365382 try {
@@ -369,7 +386,8 @@ public void processInjection(Object bean) throws BeansException {
369386 throw ex ;
370387 }
371388 catch (Throwable ex ) {
372- throw new BeanCreationException ("Injection of autowired dependencies failed for class [" + clazz + "]" , ex );
389+ throw new BeanCreationException (
390+ "Injection of autowired dependencies failed for class [" + clazz + "]" , ex );
373391 }
374392 }
375393
@@ -405,8 +423,7 @@ private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
405423 Class <?> targetClass = clazz ;
406424
407425 do {
408- final LinkedList <InjectionMetadata .InjectedElement > currElements =
409- new LinkedList <>();
426+ final LinkedList <InjectionMetadata .InjectedElement > currElements = new LinkedList <>();
410427
411428 ReflectionUtils .doWithLocalFields (targetClass , new ReflectionUtils .FieldCallback () {
412429 @ Override
@@ -442,7 +459,8 @@ public void doWith(Method method) throws IllegalArgumentException, IllegalAccess
442459 }
443460 if (method .getParameterCount () == 0 ) {
444461 if (logger .isWarnEnabled ()) {
445- logger .warn ("Autowired annotation should be used on methods with parameters: " + method );
462+ logger .warn ("Autowired annotation should only be used on methods with parameters: " +
463+ method );
446464 }
447465 }
448466 boolean required = determineRequiredStatus (ann );
@@ -625,15 +643,15 @@ protected void inject(Object bean, String beanName, PropertyValues pvs) throws T
625643 Class <?>[] paramTypes = method .getParameterTypes ();
626644 arguments = new Object [paramTypes .length ];
627645 DependencyDescriptor [] descriptors = new DependencyDescriptor [paramTypes .length ];
628- Set <String > autowiredBeanNames = new LinkedHashSet <>(paramTypes .length );
646+ Set <String > autowiredBeans = new LinkedHashSet <>(paramTypes .length );
629647 TypeConverter typeConverter = beanFactory .getTypeConverter ();
630648 for (int i = 0 ; i < arguments .length ; i ++) {
631649 MethodParameter methodParam = new MethodParameter (method , i );
632650 DependencyDescriptor currDesc = new DependencyDescriptor (methodParam , this .required );
633651 currDesc .setContainingClass (bean .getClass ());
634652 descriptors [i ] = currDesc ;
635653 try {
636- Object arg = beanFactory .resolveDependency (currDesc , beanName , autowiredBeanNames , typeConverter );
654+ Object arg = beanFactory .resolveDependency (currDesc , beanName , autowiredBeans , typeConverter );
637655 if (arg == null && !this .required ) {
638656 arguments = null ;
639657 break ;
@@ -651,9 +669,9 @@ protected void inject(Object bean, String beanName, PropertyValues pvs) throws T
651669 for (int i = 0 ; i < arguments .length ; i ++) {
652670 this .cachedMethodArguments [i ] = descriptors [i ];
653671 }
654- registerDependentBeans (beanName , autowiredBeanNames );
655- if (autowiredBeanNames .size () == paramTypes .length ) {
656- Iterator <String > it = autowiredBeanNames .iterator ();
672+ registerDependentBeans (beanName , autowiredBeans );
673+ if (autowiredBeans .size () == paramTypes .length ) {
674+ Iterator <String > it = autowiredBeans .iterator ();
657675 for (int i = 0 ; i < paramTypes .length ; i ++) {
658676 String autowiredBeanName = it .next ();
659677 if (beanFactory .containsBean (autowiredBeanName )) {
@@ -702,19 +720,19 @@ private Object[] resolveCachedArguments(String beanName) {
702720 @ SuppressWarnings ("serial" )
703721 private static class ShortcutDependencyDescriptor extends DependencyDescriptor {
704722
705- private final String shortcutName ;
723+ private final String shortcut ;
706724
707725 private final Class <?> requiredType ;
708726
709- public ShortcutDependencyDescriptor (DependencyDescriptor original , String shortcutName , Class <?> requiredType ) {
727+ public ShortcutDependencyDescriptor (DependencyDescriptor original , String shortcut , Class <?> requiredType ) {
710728 super (original );
711- this .shortcutName = shortcutName ;
729+ this .shortcut = shortcut ;
712730 this .requiredType = requiredType ;
713731 }
714732
715733 @ Override
716734 public Object resolveShortcut (BeanFactory beanFactory ) {
717- return resolveCandidate (this .shortcutName , this .requiredType , beanFactory );
735+ return resolveCandidate (this .shortcut , this .requiredType , beanFactory );
718736 }
719737 }
720738
0 commit comments