demo-annotationtypefilter.zip Hi, first time here. Please bear with me if this report has to be fixed somehow.

We have recently upgraded Spring Boot 2.1.16 to 2.3.3 and we have found differences in the behaviour of ClassPathScanningCandidateComponentProvider which are breaking something we had working.

Essentially, we have a @Configuration class implementing ResourceLoaderAware, EnvironmentAware, ImportBeanDefinitionRegistrar which includes an snippet like this one:

    ClassPathScanningCandidateComponentProvider scanner = getScanner();
    AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(HappyAnnotation.class);
    scanner.addIncludeFilter(annotationTypeFilter);
    scanner.setResourceLoader(this.resourceLoader);
    Set<BeanDefinition> candidateComponents = scanner.findCandidateComponents("com");

With this, we would be able to find interfaces in the classpath annotated with @HappyAnnotation, to which we would do some operation later to have them registered in the Spring context. Now the candidateComponents is empty, so nothing will be registered.

We have noticed several things:

  • ClassPathScanningCandidateComponentProvider makes use of a SimpleMetadataReader at some point. The implementation for it has changed.
  • The former implementation for SimpleMetadataReader made use of a visitor called AnnotationMetadataReadingVisitor. It has been deprecated and SimpleAnnotationMetadataReadingVisitor is being used instead.
  • The new implementation of SimpleMetadataReader ends up with an attribute annotationMetadata of type SimpleAnnotationMetadata, which at the same time has annotations (TypeMappedAnnotations) with an annotationFilter being shown in debug as "All annotations filtered", which suggests all annotations are ignored.
  • I have seen that AnnotationMetadataReadingVisitor is mentioned to be deprecated and replaced for the other one but no public replacement for it is being provided, as per documentation. I am not really sure this pattern we use is valid anymore.

I attach an small project that reproduces the issue. Just change the commented spring boot parent version in the pom for the other one to reproduce.

If not a bug and if time allows, please forward me to some documentation which explains how to get our Set<BeanDefinition> correctly in this version.

Thanks in advance,

JP

Comment From: snicoll

Thanks for the sample, that is very useful.

@HappyAnnotation does not have any retention. Adding @Retention(RetentionPolicy.RUNTIME) makes it work with Spring Boot 2.3.3. Arguably, such setup has always been invalid considering that the annotation should be discoverable at runtime.

Comment From: sbrannen

This is indeed a duplicate of #23901, and the change is documented in the Core Container section of the Upgrading to Version 5.2 notes.