1
1
/*
2
- * Copyright 2002-2020 the original author or authors.
2
+ * Copyright 2002-2021 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
@@ -628,45 +628,58 @@ protected void inject(Object bean, @Nullable String beanName, @Nullable Property
628
628
Field field = (Field ) this .member ;
629
629
Object value ;
630
630
if (this .cached ) {
631
- value = resolvedCachedArgument (beanName , this .cachedFieldValue );
632
- }
633
- else {
634
- DependencyDescriptor desc = new DependencyDescriptor (field , this .required );
635
- desc .setContainingClass (bean .getClass ());
636
- Set <String > autowiredBeanNames = new LinkedHashSet <>(1 );
637
- Assert .state (beanFactory != null , "No BeanFactory available" );
638
- TypeConverter typeConverter = beanFactory .getTypeConverter ();
639
631
try {
640
- value = beanFactory .resolveDependency (desc , beanName , autowiredBeanNames , typeConverter );
641
- }
642
- catch (BeansException ex ) {
643
- throw new UnsatisfiedDependencyException (null , beanName , new InjectionPoint (field ), ex );
632
+ value = resolvedCachedArgument (beanName , this .cachedFieldValue );
644
633
}
645
- synchronized (this ) {
646
- if (!this .cached ) {
647
- Object cachedFieldValue = null ;
648
- if (value != null || this .required ) {
649
- cachedFieldValue = desc ;
650
- registerDependentBeans (beanName , autowiredBeanNames );
651
- if (autowiredBeanNames .size () == 1 ) {
652
- String autowiredBeanName = autowiredBeanNames .iterator ().next ();
653
- if (beanFactory .containsBean (autowiredBeanName ) &&
654
- beanFactory .isTypeMatch (autowiredBeanName , field .getType ())) {
655
- cachedFieldValue = new ShortcutDependencyDescriptor (
656
- desc , autowiredBeanName , field .getType ());
657
- }
658
- }
659
- }
660
- this .cachedFieldValue = cachedFieldValue ;
661
- this .cached = true ;
662
- }
634
+ catch (NoSuchBeanDefinitionException ex ) {
635
+ // Unexpected removal of target bean for cached argument -> re-resolve
636
+ value = resolveFieldValue (field , bean , beanName );
663
637
}
664
638
}
639
+ else {
640
+ value = resolveFieldValue (field , bean , beanName );
641
+ }
665
642
if (value != null ) {
666
643
ReflectionUtils .makeAccessible (field );
667
644
field .set (bean , value );
668
645
}
669
646
}
647
+
648
+ @ Nullable
649
+ private Object resolveFieldValue (Field field , Object bean , @ Nullable String beanName ) {
650
+ DependencyDescriptor desc = new DependencyDescriptor (field , this .required );
651
+ desc .setContainingClass (bean .getClass ());
652
+ Set <String > autowiredBeanNames = new LinkedHashSet <>(1 );
653
+ Assert .state (beanFactory != null , "No BeanFactory available" );
654
+ TypeConverter typeConverter = beanFactory .getTypeConverter ();
655
+ Object value ;
656
+ try {
657
+ value = beanFactory .resolveDependency (desc , beanName , autowiredBeanNames , typeConverter );
658
+ }
659
+ catch (BeansException ex ) {
660
+ throw new UnsatisfiedDependencyException (null , beanName , new InjectionPoint (field ), ex );
661
+ }
662
+ synchronized (this ) {
663
+ if (!this .cached ) {
664
+ Object cachedFieldValue = null ;
665
+ if (value != null || this .required ) {
666
+ cachedFieldValue = desc ;
667
+ registerDependentBeans (beanName , autowiredBeanNames );
668
+ if (autowiredBeanNames .size () == 1 ) {
669
+ String autowiredBeanName = autowiredBeanNames .iterator ().next ();
670
+ if (beanFactory .containsBean (autowiredBeanName ) &&
671
+ beanFactory .isTypeMatch (autowiredBeanName , field .getType ())) {
672
+ cachedFieldValue = new ShortcutDependencyDescriptor (
673
+ desc , autowiredBeanName , field .getType ());
674
+ }
675
+ }
676
+ }
677
+ this .cachedFieldValue = cachedFieldValue ;
678
+ this .cached = true ;
679
+ }
680
+ }
681
+ return value ;
682
+ }
670
683
}
671
684
672
685
@@ -695,59 +708,17 @@ protected void inject(Object bean, @Nullable String beanName, @Nullable Property
695
708
Method method = (Method ) this .member ;
696
709
Object [] arguments ;
697
710
if (this .cached ) {
698
- // Shortcut for avoiding synchronization...
699
- arguments = resolveCachedArguments (beanName );
700
- }
701
- else {
702
- int argumentCount = method .getParameterCount ();
703
- arguments = new Object [argumentCount ];
704
- DependencyDescriptor [] descriptors = new DependencyDescriptor [argumentCount ];
705
- Set <String > autowiredBeans = new LinkedHashSet <>(argumentCount );
706
- Assert .state (beanFactory != null , "No BeanFactory available" );
707
- TypeConverter typeConverter = beanFactory .getTypeConverter ();
708
- for (int i = 0 ; i < arguments .length ; i ++) {
709
- MethodParameter methodParam = new MethodParameter (method , i );
710
- DependencyDescriptor currDesc = new DependencyDescriptor (methodParam , this .required );
711
- currDesc .setContainingClass (bean .getClass ());
712
- descriptors [i ] = currDesc ;
713
- try {
714
- Object arg = beanFactory .resolveDependency (currDesc , beanName , autowiredBeans , typeConverter );
715
- if (arg == null && !this .required ) {
716
- arguments = null ;
717
- break ;
718
- }
719
- arguments [i ] = arg ;
720
- }
721
- catch (BeansException ex ) {
722
- throw new UnsatisfiedDependencyException (null , beanName , new InjectionPoint (methodParam ), ex );
723
- }
711
+ try {
712
+ arguments = resolveCachedArguments (beanName );
724
713
}
725
- synchronized (this ) {
726
- if (!this .cached ) {
727
- if (arguments != null ) {
728
- DependencyDescriptor [] cachedMethodArguments = Arrays .copyOf (descriptors , arguments .length );
729
- registerDependentBeans (beanName , autowiredBeans );
730
- if (autowiredBeans .size () == argumentCount ) {
731
- Iterator <String > it = autowiredBeans .iterator ();
732
- Class <?>[] paramTypes = method .getParameterTypes ();
733
- for (int i = 0 ; i < paramTypes .length ; i ++) {
734
- String autowiredBeanName = it .next ();
735
- if (beanFactory .containsBean (autowiredBeanName ) &&
736
- beanFactory .isTypeMatch (autowiredBeanName , paramTypes [i ])) {
737
- cachedMethodArguments [i ] = new ShortcutDependencyDescriptor (
738
- descriptors [i ], autowiredBeanName , paramTypes [i ]);
739
- }
740
- }
741
- }
742
- this .cachedMethodArguments = cachedMethodArguments ;
743
- }
744
- else {
745
- this .cachedMethodArguments = null ;
746
- }
747
- this .cached = true ;
748
- }
714
+ catch (NoSuchBeanDefinitionException ex ) {
715
+ // Unexpected removal of target bean for cached argument -> re-resolve
716
+ arguments = resolveMethodArguments (method , bean , beanName );
749
717
}
750
718
}
719
+ else {
720
+ arguments = resolveMethodArguments (method , bean , beanName );
721
+ }
751
722
if (arguments != null ) {
752
723
try {
753
724
ReflectionUtils .makeAccessible (method );
@@ -771,6 +742,59 @@ private Object[] resolveCachedArguments(@Nullable String beanName) {
771
742
}
772
743
return arguments ;
773
744
}
745
+
746
+ @ Nullable
747
+ private Object [] resolveMethodArguments (Method method , Object bean , @ Nullable String beanName ) {
748
+ int argumentCount = method .getParameterCount ();
749
+ Object [] arguments = new Object [argumentCount ];
750
+ DependencyDescriptor [] descriptors = new DependencyDescriptor [argumentCount ];
751
+ Set <String > autowiredBeans = new LinkedHashSet <>(argumentCount );
752
+ Assert .state (beanFactory != null , "No BeanFactory available" );
753
+ TypeConverter typeConverter = beanFactory .getTypeConverter ();
754
+ for (int i = 0 ; i < arguments .length ; i ++) {
755
+ MethodParameter methodParam = new MethodParameter (method , i );
756
+ DependencyDescriptor currDesc = new DependencyDescriptor (methodParam , this .required );
757
+ currDesc .setContainingClass (bean .getClass ());
758
+ descriptors [i ] = currDesc ;
759
+ try {
760
+ Object arg = beanFactory .resolveDependency (currDesc , beanName , autowiredBeans , typeConverter );
761
+ if (arg == null && !this .required ) {
762
+ arguments = null ;
763
+ break ;
764
+ }
765
+ arguments [i ] = arg ;
766
+ }
767
+ catch (BeansException ex ) {
768
+ throw new UnsatisfiedDependencyException (null , beanName , new InjectionPoint (methodParam ), ex );
769
+ }
770
+ }
771
+ synchronized (this ) {
772
+ if (!this .cached ) {
773
+ if (arguments != null ) {
774
+ DependencyDescriptor [] cachedMethodArguments = Arrays .copyOf (descriptors , arguments .length );
775
+ registerDependentBeans (beanName , autowiredBeans );
776
+ if (autowiredBeans .size () == argumentCount ) {
777
+ Iterator <String > it = autowiredBeans .iterator ();
778
+ Class <?>[] paramTypes = method .getParameterTypes ();
779
+ for (int i = 0 ; i < paramTypes .length ; i ++) {
780
+ String autowiredBeanName = it .next ();
781
+ if (beanFactory .containsBean (autowiredBeanName ) &&
782
+ beanFactory .isTypeMatch (autowiredBeanName , paramTypes [i ])) {
783
+ cachedMethodArguments [i ] = new ShortcutDependencyDescriptor (
784
+ descriptors [i ], autowiredBeanName , paramTypes [i ]);
785
+ }
786
+ }
787
+ }
788
+ this .cachedMethodArguments = cachedMethodArguments ;
789
+ }
790
+ else {
791
+ this .cachedMethodArguments = null ;
792
+ }
793
+ this .cached = true ;
794
+ }
795
+ }
796
+ return arguments ;
797
+ }
774
798
}
775
799
776
800
0 commit comments