2424import java .util .Collections ;
2525import java .util .HashMap ;
2626import java .util .HashSet ;
27+ import java .util .LinkedHashMap ;
2728import java .util .LinkedHashSet ;
2829import java .util .List ;
2930import java .util .Locale ;
3031import java .util .Map ;
3132import java .util .Map .Entry ;
3233import java .util .Set ;
34+ import java .util .function .BiPredicate ;
3335import java .util .function .Predicate ;
3436
3537import org .springframework .aop .scope .ScopedProxyUtils ;
3638import org .springframework .beans .factory .BeanFactory ;
3739import org .springframework .beans .factory .HierarchicalBeanFactory ;
3840import org .springframework .beans .factory .ListableBeanFactory ;
41+ import org .springframework .beans .factory .NoSuchBeanDefinitionException ;
3942import org .springframework .beans .factory .config .BeanDefinition ;
4043import org .springframework .beans .factory .config .ConfigurableListableBeanFactory ;
4144import org .springframework .beans .factory .config .SingletonBeanRegistry ;
@@ -211,26 +214,30 @@ protected final MatchResult getMatchingBeans(Spec<?> spec) {
211214 Set <String > beansIgnoredByType = getNamesOfBeansIgnoredByType (classLoader , beanFactory , considerHierarchy ,
212215 spec .getIgnoredTypes (), parameterizedContainers );
213216 for (String type : spec .getTypes ()) {
214- Collection <String > typeMatches = getBeanNamesForType (classLoader , considerHierarchy , beanFactory , type ,
215- parameterizedContainers );
216- typeMatches
217- .removeIf ((match ) -> beansIgnoredByType .contains (match ) || ScopedProxyUtils .isScopedTarget (match ));
218- if (typeMatches .isEmpty ()) {
217+ Map <String , BeanDefinition > typeMatchedDefinitions = getBeanDefinitionsForType (classLoader ,
218+ considerHierarchy , beanFactory , type , parameterizedContainers );
219+ Set <String > typeMatchedNames = matchedNamesFrom (typeMatchedDefinitions ,
220+ (name , definition ) -> !beansIgnoredByType .contains (name ) && !ScopedProxyUtils .isScopedTarget (name )
221+ && (definition == null || definition .isAutowireCandidate ()));
222+ if (typeMatchedNames .isEmpty ()) {
219223 result .recordUnmatchedType (type );
220224 }
221225 else {
222- result .recordMatchedType (type , typeMatches );
226+ result .recordMatchedType (type , typeMatchedNames );
223227 }
224228 }
225229 for (String annotation : spec .getAnnotations ()) {
226- Set <String > annotationMatches = getBeanNamesForAnnotation (classLoader , beanFactory , annotation ,
227- considerHierarchy );
228- annotationMatches .removeAll (beansIgnoredByType );
229- if (annotationMatches .isEmpty ()) {
230+ Map <String , BeanDefinition > annotationMatchedDefinitions = getBeanDefinitionsForAnnotation (classLoader ,
231+ beanFactory , annotation , considerHierarchy );
232+ Set <String > annotationMatchedNames = matchedNamesFrom (annotationMatchedDefinitions ,
233+ (name , definition ) -> !beansIgnoredByType .contains (name )
234+ && (definition == null || definition .isAutowireCandidate ()));
235+ if (annotationMatchedNames .isEmpty ()) {
230236 result .recordUnmatchedAnnotation (annotation );
231237 }
232238 else {
233- result .recordMatchedAnnotation (annotation , annotationMatches );
239+ result .recordMatchedAnnotation (annotation , annotationMatchedNames );
240+
234241 }
235242 }
236243 for (String beanName : spec .getNames ()) {
@@ -244,63 +251,76 @@ protected final MatchResult getMatchingBeans(Spec<?> spec) {
244251 return result ;
245252 }
246253
254+ private Set <String > matchedNamesFrom (Map <String , BeanDefinition > namedDefinitions ,
255+ BiPredicate <String , BeanDefinition > filter ) {
256+ Set <String > matchedNames = new LinkedHashSet <>(namedDefinitions .size ());
257+ for (Entry <String , BeanDefinition > namedDefinition : namedDefinitions .entrySet ()) {
258+ if (filter .test (namedDefinition .getKey (), namedDefinition .getValue ())) {
259+ matchedNames .add (namedDefinition .getKey ());
260+ }
261+ }
262+ return matchedNames ;
263+ }
264+
247265 private Set <String > getNamesOfBeansIgnoredByType (ClassLoader classLoader , ListableBeanFactory beanFactory ,
248266 boolean considerHierarchy , Set <String > ignoredTypes , Set <Class <?>> parameterizedContainers ) {
249267 Set <String > result = null ;
250268 for (String ignoredType : ignoredTypes ) {
251- Collection <String > ignoredNames = getBeanNamesForType (classLoader , considerHierarchy , beanFactory ,
252- ignoredType , parameterizedContainers );
269+ Collection <String > ignoredNames = getBeanDefinitionsForType (classLoader , considerHierarchy , beanFactory ,
270+ ignoredType , parameterizedContainers )
271+ .keySet ();
253272 result = addAll (result , ignoredNames );
254273 }
255274 return (result != null ) ? result : Collections .emptySet ();
256275 }
257276
258- private Set <String > getBeanNamesForType (ClassLoader classLoader , boolean considerHierarchy ,
277+ private Map <String , BeanDefinition > getBeanDefinitionsForType (ClassLoader classLoader , boolean considerHierarchy ,
259278 ListableBeanFactory beanFactory , String type , Set <Class <?>> parameterizedContainers ) throws LinkageError {
260279 try {
261- return getBeanNamesForType (beanFactory , considerHierarchy , resolve (type , classLoader ),
280+ return getBeanDefinitionsForType (beanFactory , considerHierarchy , resolve (type , classLoader ),
262281 parameterizedContainers );
263282 }
264283 catch (ClassNotFoundException | NoClassDefFoundError ex ) {
265- return Collections .emptySet ();
284+ return Collections .emptyMap ();
266285 }
267286 }
268287
269- private Set <String > getBeanNamesForType (ListableBeanFactory beanFactory , boolean considerHierarchy , Class <?> type ,
270- Set <Class <?>> parameterizedContainers ) {
271- Set <String > result = collectBeanNamesForType (beanFactory , considerHierarchy , type , parameterizedContainers ,
272- null );
273- return (result != null ) ? result : Collections .emptySet ();
288+ private Map <String , BeanDefinition > getBeanDefinitionsForType (ListableBeanFactory beanFactory ,
289+ boolean considerHierarchy , Class <?> type , Set <Class <?>> parameterizedContainers ) {
290+ Map <String , BeanDefinition > result = collectBeanDefinitionsForType (beanFactory , considerHierarchy , type ,
291+ parameterizedContainers , null );
292+ return (result != null ) ? result : Collections .emptyMap ();
274293 }
275294
276- private Set <String > collectBeanNamesForType (ListableBeanFactory beanFactory , boolean considerHierarchy ,
277- Class <?> type , Set <Class <?>> parameterizedContainers , Set <String > result ) {
278- result = addAll (result , beanFactory .getBeanNamesForType (type , true , false ));
295+ private Map <String , BeanDefinition > collectBeanDefinitionsForType (ListableBeanFactory beanFactory ,
296+ boolean considerHierarchy , Class <?> type , Set <Class <?>> parameterizedContainers ,
297+ Map <String , BeanDefinition > result ) {
298+ result = putAll (result , beanFactory .getBeanNamesForType (type , true , false ), beanFactory );
279299 for (Class <?> container : parameterizedContainers ) {
280300 ResolvableType generic = ResolvableType .forClassWithGenerics (container , type );
281- result = addAll (result , beanFactory .getBeanNamesForType (generic , true , false ));
301+ result = putAll (result , beanFactory .getBeanNamesForType (generic , true , false ), beanFactory );
282302 }
283303 if (considerHierarchy && beanFactory instanceof HierarchicalBeanFactory hierarchicalBeanFactory ) {
284304 BeanFactory parent = hierarchicalBeanFactory .getParentBeanFactory ();
285305 if (parent instanceof ListableBeanFactory listableBeanFactory ) {
286- result = collectBeanNamesForType (listableBeanFactory , considerHierarchy , type , parameterizedContainers ,
287- result );
306+ result = collectBeanDefinitionsForType (listableBeanFactory , considerHierarchy , type ,
307+ parameterizedContainers , result );
288308 }
289309 }
290310 return result ;
291311 }
292312
293- private Set <String > getBeanNamesForAnnotation (ClassLoader classLoader , ConfigurableListableBeanFactory beanFactory ,
294- String type , boolean considerHierarchy ) throws LinkageError {
295- Set <String > result = null ;
313+ private Map <String , BeanDefinition > getBeanDefinitionsForAnnotation (ClassLoader classLoader ,
314+ ConfigurableListableBeanFactory beanFactory , String type , boolean considerHierarchy ) throws LinkageError {
315+ Map <String , BeanDefinition > result = null ;
296316 try {
297- result = collectBeanNamesForAnnotation (beanFactory , resolveAnnotationType (classLoader , type ),
317+ result = collectBeanDefinitionsForAnnotation (beanFactory , resolveAnnotationType (classLoader , type ),
298318 considerHierarchy , result );
299319 }
300320 catch (ClassNotFoundException ex ) {
301321 // Continue
302322 }
303- return (result != null ) ? result : Collections .emptySet ();
323+ return (result != null ) ? result : Collections .emptyMap ();
304324 }
305325
306326 @ SuppressWarnings ("unchecked" )
@@ -309,13 +329,14 @@ private Class<? extends Annotation> resolveAnnotationType(ClassLoader classLoade
309329 return (Class <? extends Annotation >) resolve (type , classLoader );
310330 }
311331
312- private Set <String > collectBeanNamesForAnnotation (ListableBeanFactory beanFactory ,
313- Class <? extends Annotation > annotationType , boolean considerHierarchy , Set <String > result ) {
314- result = addAll (result , getBeanNamesForAnnotation (beanFactory , annotationType ));
332+ private Map <String , BeanDefinition > collectBeanDefinitionsForAnnotation (ListableBeanFactory beanFactory ,
333+ Class <? extends Annotation > annotationType , boolean considerHierarchy , Map <String , BeanDefinition > result ) {
334+ result = putAll (result , getBeanNamesForAnnotation (beanFactory , annotationType ), beanFactory );
315335 if (considerHierarchy ) {
316336 BeanFactory parent = ((HierarchicalBeanFactory ) beanFactory ).getParentBeanFactory ();
317337 if (parent instanceof ListableBeanFactory listableBeanFactory ) {
318- result = collectBeanNamesForAnnotation (listableBeanFactory , annotationType , considerHierarchy , result );
338+ result = collectBeanDefinitionsForAnnotation (listableBeanFactory , annotationType , considerHierarchy ,
339+ result );
319340 }
320341 }
321342 return result ;
@@ -453,12 +474,27 @@ private static Set<String> addAll(Set<String> result, Collection<String> additio
453474 return result ;
454475 }
455476
456- private static Set <String > addAll (Set <String > result , String [] additional ) {
457- if (ObjectUtils .isEmpty (additional )) {
477+ private static Map <String , BeanDefinition > putAll (Map <String , BeanDefinition > result , String [] beanNames ,
478+ ListableBeanFactory beanFactory ) {
479+ if (ObjectUtils .isEmpty (beanNames )) {
458480 return result ;
459481 }
460- result = (result != null ) ? result : new LinkedHashSet <>();
461- Collections .addAll (result , additional );
482+ if (result == null ) {
483+ result = new LinkedHashMap <>();
484+ }
485+ for (String beanName : beanNames ) {
486+ if (beanFactory instanceof ConfigurableListableBeanFactory clbf ) {
487+ try {
488+ result .put (beanName , clbf .getBeanDefinition (beanName ));
489+ }
490+ catch (NoSuchBeanDefinitionException ex ) {
491+ result .put (beanName , null );
492+ }
493+ }
494+ else {
495+ result .put (beanName , null );
496+ }
497+ }
462498 return result ;
463499 }
464500
0 commit comments