Affects: spring-context 6.0.4


I think that @PropertySource should be effective when it's declared on an interface that an autoconfiguration class implements. For example:

I have a hierarchical structure with some @AutoConfiguration classes. For example:


@PropertySource(value = "classpath:/props/${custom.property.source}", factory = CustomPropertiesFactory.class)
public interface BaseConfig {

}

@AutoConfiguration
@ConditionalOnProperty(prefix = "property.value", name = "enabled", havingValue = "true")
public class ImplNumberOne implements BaseConfig {

}

@AutoConfiguration
@ConditionalOnProperty(prefix = "other.property.value", name = "enabled", havingValue = "true")
public class ImplNumberTwo implements BaseConfig {

}

I've observed that @PropertySource is not respected with this setup and I have to move the annotation to the concrete classes. I think that it should still work when declared on the interface.

Comment From: adase11

I made a branch in an existing demo application that demonstrates this here.

Using the property autoconfiguration.file in application.properties the configuration can be changed to demonstrate @PropertySource being used on an interface vs a concrete class.

Comment From: snicoll

Thanks for the suggestion but we the reference guide describes how the annotation should be used, in particular that it should be added directly to the @Configuration class.

Note also that @PropertySource is not a great candidate for auto-configurations, see the ref guide.

Comment From: adase11

@snicoll thanks for looking at this. I have two clarifying questions if you don't mind taking a look at them.

Question 1

the reference guide describes how the annotation should be used, in particular that it should be added directly to the @Configuration class.

Are you referring to the note that says:

The @PropertySource annotation is repeatable, according to Java 8 conventions. However, all such @PropertySource annotations need to be declared at the same level, either directly on the configuration class or as meta-annotations within the same custom annotation.

I took that to be addressing the repeatable nature of @PropertySource and directly on the configuration class was meant to address the contrast between having some @PropertySource on the configuration class and some on the custom annotation vs making sure they were all either on the configuration class or all on the same custom annotation.

Question 2

Note also that @PropertySource is not a great candidate for auto-configurations, see the ref guide.

Are you referring to this information, or was there another item in the ref guide that you were referring to that's addressing @PropertySource and auto-configuration?

Please note that such property sources are not added to the Environment until the application context is being refreshed. This is too late to configure certain properties such as logging.* and spring.main.* which are read before refresh begins.

Comment From: snicoll

Question 1: Yes they need to be declared at the same level but nothing states either you could annotate them on an interface that your configuration class implements. This really is a stereotype that's tied to the configuration class so it makes sense to strongly associate it. Besides, the annotation is not inherited so that shouldn't come as a surprise if you look at it.

Question 2: Yes. The property source being evaluated late means it's really a bad idea to use them with auto-configurations. Besides, Spring Boot has way more powerful ways to compose the environment.

If you have further questions, please direct them to StackOverflow.

Comment From: adase11

Thanks!