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!