This issue describes an issue encountered when trying to upgrade from Spring Boot 2.1.x to Spring Boot 2.2.x (tried with 2.2.3 & 2.2.4).

We are currently using a set of meta annotations with ConditionalOnProperty in order to instanciate some beans instead of others according to a runtime configuration. So, we have for example two meta annotation like this :

@ConditionalOnProperty(
        value = {"meta.condition1"},
        havingValue = "true"
)
public @interface MetaAnnotationCondition1 {
}

@ConditionalOnProperty(
        value = {"meta.condition2"},
        havingValue = "true"
)
public @interface MetaAnnotationCondition2 {
}

And some beans annotated with it like that :

@MetaAnnotationCondition1
@Component
public class ConditionalBeanA implements ConditionalBean {
}

@MetaAnnotationCondition2
@Component
public class ConditionalBeanB implements ConditionalBean {
}

With spring boot 2.1, when positioning application.properties withmeta.condition1=true and meta.condition2=false the correct bean is instanciated. With spring boot 2.2, the two beans are instanciated, so my application doest not start due to multiple beans found when autowiring.

An reproduction example can be found here : https://github.com/olivierboudet/springboot-2.2-issue-meta-conditional Just start the application on the master branch, which is SB 2.1.12, the application starts correctly. Then start the springboot-2.2 branch, the application crashes on startup.

Is this an intended behavior of springboot 2.2 or is it a bug ? Is this is intended, what is the correct way to fix this sort of things ?

FYI, I just do a little of debugging and I saw that : - with SB 2.1, in ConditionEvalutator.shouldSkip(), the instance of AnnotatedTypeMetadata is of type AnnotationMetadataReadingVisitor - with SB 2.2, in ConditionEvalutator.shouldSkip(), the instance of AnnotatedTypeMetadata is of type SimpleAnnotationMetadata which does not check for inherited annotations.

Comment From: snicoll

Thanks for the sample. Your meta-annotations do not have any runtime retention so arguably this should never have worked in the first place. Spring Framework 5.2 is more consistent with metadata handling, see https://github.com/spring-projects/spring-framework/issues/23901 for more details.

Adding the following to the two meta annotations fixes your project and works with both Spring Boot 2.1 and Spring Boot 2.2:

@Retention(RetentionPolicy.RUNTIME)

Comment From: olivierboudet

wow thank you for the reactivity. I can confirm that the missing @Retention annotation was the issue.