|
1 | 1 | /*
|
2 |
| - * Copyright 2002-2016 the original author or authors. |
| 2 | + * Copyright 2002-2017 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.
|
|
30 | 30 | import org.springframework.beans.factory.BeanDefinitionStoreException;
|
31 | 31 | import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
|
32 | 32 | import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
|
| 33 | +import org.springframework.beans.factory.annotation.Lookup; |
33 | 34 | import org.springframework.beans.factory.config.BeanDefinition;
|
34 | 35 | import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
35 | 36 | import org.springframework.context.ResourceLoaderAware;
|
|
43 | 44 | import org.springframework.core.io.ResourceLoader;
|
44 | 45 | import org.springframework.core.io.support.ResourcePatternResolver;
|
45 | 46 | import org.springframework.core.io.support.ResourcePatternUtils;
|
| 47 | +import org.springframework.core.type.AnnotationMetadata; |
46 | 48 | import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
|
47 | 49 | import org.springframework.core.type.classreading.MetadataReader;
|
48 | 50 | import org.springframework.core.type.classreading.MetadataReaderFactory;
|
@@ -294,7 +296,62 @@ public Set<BeanDefinition> findCandidateComponents(String basePackage) {
|
294 | 296 | }
|
295 | 297 | }
|
296 | 298 |
|
297 |
| - protected Set<BeanDefinition> addCandidateComponentsFromIndex(String basePackage) { |
| 299 | + /** |
| 300 | + * Determine if the index can be used by this instance. |
| 301 | + * @return {@code true} if the index is available and the configuration of this |
| 302 | + * instance is supported by it, {@code false} otherwise |
| 303 | + * @since 5.0 |
| 304 | + */ |
| 305 | + protected boolean isIndexSupported() { |
| 306 | + if (this.componentsIndex == null) { |
| 307 | + return false; |
| 308 | + } |
| 309 | + for (TypeFilter includeFilter : this.includeFilters) { |
| 310 | + if (!isIndexSupportsIncludeFilter(includeFilter)) { |
| 311 | + return false; |
| 312 | + } |
| 313 | + } |
| 314 | + return true; |
| 315 | + } |
| 316 | + |
| 317 | + /** |
| 318 | + * Determine if the specified include {@link TypeFilter} is supported by the index. |
| 319 | + * @param filter the filter to check |
| 320 | + * @return whether the index supports this include filter |
| 321 | + * @since 5.0 |
| 322 | + * @see #extractStereotype(TypeFilter) |
| 323 | + */ |
| 324 | + protected boolean isIndexSupportsIncludeFilter(TypeFilter filter) { |
| 325 | + if (filter instanceof AnnotationTypeFilter) { |
| 326 | + Class<? extends Annotation> annotation = ((AnnotationTypeFilter) filter).getAnnotationType(); |
| 327 | + return (AnnotationUtils.isAnnotationDeclaredLocally(Indexed.class, annotation) || |
| 328 | + annotation.getName().startsWith("javax.")); |
| 329 | + } |
| 330 | + if (filter instanceof AssignableTypeFilter) { |
| 331 | + Class<?> target = ((AssignableTypeFilter) filter).getTargetType(); |
| 332 | + return AnnotationUtils.isAnnotationDeclaredLocally(Indexed.class, target); |
| 333 | + } |
| 334 | + return false; |
| 335 | + } |
| 336 | + |
| 337 | + /** |
| 338 | + * Extract the stereotype to use for the specified compatible filter. |
| 339 | + * @param filter the filter to handle |
| 340 | + * @return the stereotype in the index matching this filter |
| 341 | + * @since 5.0 |
| 342 | + * @see #isIndexSupportsIncludeFilter(TypeFilter) |
| 343 | + */ |
| 344 | + protected String extractStereotype(TypeFilter filter) { |
| 345 | + if (filter instanceof AnnotationTypeFilter) { |
| 346 | + return ((AnnotationTypeFilter) filter).getAnnotationType().getName(); |
| 347 | + } |
| 348 | + if (filter instanceof AssignableTypeFilter) { |
| 349 | + return ((AssignableTypeFilter) filter).getTargetType().getName(); |
| 350 | + } |
| 351 | + return null; |
| 352 | + } |
| 353 | + |
| 354 | + private Set<BeanDefinition> addCandidateComponentsFromIndex(String basePackage) { |
298 | 355 | Set<BeanDefinition> candidates = new LinkedHashSet<>();
|
299 | 356 | try {
|
300 | 357 | Set<String> types = new HashSet<>();
|
@@ -337,7 +394,7 @@ protected Set<BeanDefinition> addCandidateComponentsFromIndex(String basePackage
|
337 | 394 | return candidates;
|
338 | 395 | }
|
339 | 396 |
|
340 |
| - protected Set<BeanDefinition> scanCandidateComponents(String basePackage) { |
| 397 | + private Set<BeanDefinition> scanCandidateComponents(String basePackage) { |
341 | 398 | Set<BeanDefinition> candidates = new LinkedHashSet<>();
|
342 | 399 | try {
|
343 | 400 | String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
|
@@ -440,66 +497,18 @@ private boolean isConditionMatch(MetadataReader metadataReader) {
|
440 | 497 |
|
441 | 498 | /**
|
442 | 499 | * Determine whether the given bean definition qualifies as candidate.
|
443 |
| - * <p>The default implementation checks whether the class is concrete |
444 |
| - * (i.e. not abstract and not an interface). Can be overridden in subclasses. |
| 500 | + * <p>The default implementation checks whether the class is not an interface |
| 501 | + * and not dependent on an enclosing class. |
| 502 | + * <p>Can be overridden in subclasses. |
445 | 503 | * @param beanDefinition the bean definition to check
|
446 | 504 | * @return whether the bean definition qualifies as a candidate component
|
447 | 505 | */
|
448 | 506 | protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
|
449 |
| - return (beanDefinition.getMetadata().isConcrete() && beanDefinition.getMetadata().isIndependent()); |
| 507 | + AnnotationMetadata metadata = beanDefinition.getMetadata(); |
| 508 | + return (metadata.isIndependent() && (metadata.isConcrete() || |
| 509 | + (metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName())))); |
450 | 510 | }
|
451 | 511 |
|
452 |
| - /** |
453 |
| - * Determine if the index can be used by this instance. |
454 |
| - * @return {@code true} if the index is available and the configuration of this |
455 |
| - * instance is supported by it, {@code false otherwise}. |
456 |
| - */ |
457 |
| - protected boolean isIndexSupported() { |
458 |
| - if (this.componentsIndex == null) { |
459 |
| - return false; |
460 |
| - } |
461 |
| - for (TypeFilter includeFilter : this.includeFilters) { |
462 |
| - if (!isIndexSupportsIncludeFilter(includeFilter)) { |
463 |
| - return false; |
464 |
| - } |
465 |
| - } |
466 |
| - return true; |
467 |
| - } |
468 |
| - |
469 |
| - /** |
470 |
| - * Determine if the specified include {@link TypeFilter} is supported by the index. |
471 |
| - * @param filter the filter to check |
472 |
| - * @return whether the index supports this include filter |
473 |
| - * @see #extractStereotype(TypeFilter) |
474 |
| - */ |
475 |
| - protected boolean isIndexSupportsIncludeFilter(TypeFilter filter) { |
476 |
| - if (filter instanceof AnnotationTypeFilter) { |
477 |
| - Class<? extends Annotation> annotation = ((AnnotationTypeFilter) filter).getAnnotationType(); |
478 |
| - return (AnnotationUtils.isAnnotationDeclaredLocally(Indexed.class, annotation) |
479 |
| - || annotation.getName().startsWith("javax.")); |
480 |
| - } |
481 |
| - if (filter instanceof AssignableTypeFilter) { |
482 |
| - Class<?> target = ((AssignableTypeFilter) filter).getTargetType(); |
483 |
| - return AnnotationUtils.isAnnotationDeclaredLocally(Indexed.class, target); |
484 |
| - } |
485 |
| - return false; |
486 |
| - } |
487 |
| - |
488 |
| - /** |
489 |
| - * Extract the stereotype to use for the specified compatible filter. |
490 |
| - * @param filter the filter to handle |
491 |
| - * @return the stereotype in the index matching this filter |
492 |
| - * @see #isIndexSupportsIncludeFilter(TypeFilter) |
493 |
| - */ |
494 |
| - protected String extractStereotype(TypeFilter filter) { |
495 |
| - if (filter instanceof AnnotationTypeFilter) { |
496 |
| - return ((AnnotationTypeFilter) filter).getAnnotationType().getName(); |
497 |
| - } |
498 |
| - if (filter instanceof AssignableTypeFilter) { |
499 |
| - return ((AssignableTypeFilter) filter).getTargetType().getName(); |
500 |
| - } |
501 |
| - return null; |
502 |
| - } |
503 | 512 |
|
504 | 513 | /**
|
505 | 514 | * Clear the local metadata cache, if any, removing all cached class metadata.
|
|
0 commit comments