@@ -216,7 +216,7 @@ public int getOrder() {
216
216
}
217
217
218
218
@ Override
219
- public void setBeanFactory (BeanFactory beanFactory ) throws BeansException {
219
+ public void setBeanFactory (BeanFactory beanFactory ) {
220
220
if (!(beanFactory instanceof ConfigurableListableBeanFactory )) {
221
221
throw new IllegalArgumentException (
222
222
"AutowiredAnnotationBeanPostProcessor requires a ConfigurableListableBeanFactory" );
@@ -234,36 +234,53 @@ public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, C
234
234
}
235
235
236
236
@ 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..
238
241
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
+ }
252
257
}
253
258
}
254
- }
255
- });
259
+ });
260
+ }
261
+ catch (IllegalStateException ex ) {
262
+ throw new BeanCreationException (beanName , "Lookup method resolution failed" , ex );
263
+ }
256
264
this .lookupMethodsChecked .add (beanName );
257
265
}
258
266
259
267
// Quick check on the concurrent map first, with minimal locking.
260
268
Constructor <?>[] candidateConstructors = this .candidateConstructorsCache .get (beanClass );
261
269
if (candidateConstructors == null ) {
270
+ // Fully synchronized resolution now...
262
271
synchronized (this .candidateConstructorsCache ) {
263
272
candidateConstructors = this .candidateConstructorsCache .get (beanClass );
264
273
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 );
267
284
Constructor <?> requiredConstructor = null ;
268
285
Constructor <?> defaultConstructor = null ;
269
286
for (Constructor <?> candidate : rawCandidates ) {
@@ -316,9 +333,9 @@ else if (candidate.getParameterCount() == 0) {
316
333
}
317
334
else if (candidates .size () == 1 && logger .isWarnEnabled ()) {
318
335
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 ));
322
339
}
323
340
}
324
341
candidateConstructors = candidates .toArray (new Constructor <?>[candidates .size ()]);
@@ -357,9 +374,9 @@ public PropertyValues postProcessPropertyValues(
357
374
* 'Native' processing method for direct calls with an arbitrary target instance,
358
375
* resolving all of its fields and methods which are annotated with {@code @Autowired}.
359
376
* @param bean the target instance to process
360
- * @throws BeansException if autowiring failed
377
+ * @throws BeanCreationException if autowiring failed
361
378
*/
362
- public void processInjection (Object bean ) throws BeansException {
379
+ public void processInjection (Object bean ) throws BeanCreationException {
363
380
Class <?> clazz = bean .getClass ();
364
381
InjectionMetadata metadata = findAutowiringMetadata (clazz .getName (), clazz , null );
365
382
try {
@@ -369,7 +386,8 @@ public void processInjection(Object bean) throws BeansException {
369
386
throw ex ;
370
387
}
371
388
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 );
373
391
}
374
392
}
375
393
@@ -405,8 +423,7 @@ private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
405
423
Class <?> targetClass = clazz ;
406
424
407
425
do {
408
- final LinkedList <InjectionMetadata .InjectedElement > currElements =
409
- new LinkedList <>();
426
+ final LinkedList <InjectionMetadata .InjectedElement > currElements = new LinkedList <>();
410
427
411
428
ReflectionUtils .doWithLocalFields (targetClass , new ReflectionUtils .FieldCallback () {
412
429
@ Override
@@ -442,7 +459,8 @@ public void doWith(Method method) throws IllegalArgumentException, IllegalAccess
442
459
}
443
460
if (method .getParameterCount () == 0 ) {
444
461
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 );
446
464
}
447
465
}
448
466
boolean required = determineRequiredStatus (ann );
@@ -625,15 +643,15 @@ protected void inject(Object bean, String beanName, PropertyValues pvs) throws T
625
643
Class <?>[] paramTypes = method .getParameterTypes ();
626
644
arguments = new Object [paramTypes .length ];
627
645
DependencyDescriptor [] descriptors = new DependencyDescriptor [paramTypes .length ];
628
- Set <String > autowiredBeanNames = new LinkedHashSet <>(paramTypes .length );
646
+ Set <String > autowiredBeans = new LinkedHashSet <>(paramTypes .length );
629
647
TypeConverter typeConverter = beanFactory .getTypeConverter ();
630
648
for (int i = 0 ; i < arguments .length ; i ++) {
631
649
MethodParameter methodParam = new MethodParameter (method , i );
632
650
DependencyDescriptor currDesc = new DependencyDescriptor (methodParam , this .required );
633
651
currDesc .setContainingClass (bean .getClass ());
634
652
descriptors [i ] = currDesc ;
635
653
try {
636
- Object arg = beanFactory .resolveDependency (currDesc , beanName , autowiredBeanNames , typeConverter );
654
+ Object arg = beanFactory .resolveDependency (currDesc , beanName , autowiredBeans , typeConverter );
637
655
if (arg == null && !this .required ) {
638
656
arguments = null ;
639
657
break ;
@@ -651,9 +669,9 @@ protected void inject(Object bean, String beanName, PropertyValues pvs) throws T
651
669
for (int i = 0 ; i < arguments .length ; i ++) {
652
670
this .cachedMethodArguments [i ] = descriptors [i ];
653
671
}
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 ();
657
675
for (int i = 0 ; i < paramTypes .length ; i ++) {
658
676
String autowiredBeanName = it .next ();
659
677
if (beanFactory .containsBean (autowiredBeanName )) {
@@ -702,19 +720,19 @@ private Object[] resolveCachedArguments(String beanName) {
702
720
@ SuppressWarnings ("serial" )
703
721
private static class ShortcutDependencyDescriptor extends DependencyDescriptor {
704
722
705
- private final String shortcutName ;
723
+ private final String shortcut ;
706
724
707
725
private final Class <?> requiredType ;
708
726
709
- public ShortcutDependencyDescriptor (DependencyDescriptor original , String shortcutName , Class <?> requiredType ) {
727
+ public ShortcutDependencyDescriptor (DependencyDescriptor original , String shortcut , Class <?> requiredType ) {
710
728
super (original );
711
- this .shortcutName = shortcutName ;
729
+ this .shortcut = shortcut ;
712
730
this .requiredType = requiredType ;
713
731
}
714
732
715
733
@ Override
716
734
public Object resolveShortcut (BeanFactory beanFactory ) {
717
- return resolveCandidate (this .shortcutName , this .requiredType , beanFactory );
735
+ return resolveCandidate (this .shortcut , this .requiredType , beanFactory );
718
736
}
719
737
}
720
738
0 commit comments