2

I have noticed there are certain properties used during startup that can only be set in the application.properties.

For example:

src/main/java/foo/bar/Foo.java

@SpringBootApplication
public class Foo {

    private static final Logger log = LoggerFactory.getLogger(Foo.class);

    public static void main(String... args) {
        ApplicationContext appContext = SpringApplication.run(Foo.class, args);
        log.info(appContext.getEnvironment().getProperty("spring.profiles.active"));
    }

}

src/main/resources/application.properties

spring.profiles.active=dev

console logs:

09:23:48.827 : The following profiles are active: dev
09:23:50.832 : dev

The profile is recognized at startup as dev and is available in the Environment. This is the expected behavior.

However, if I move the same property from application.properties to foo.properties and load it as a @PropertySource, the behavior changes.

src/main/java/foo/bar/FooConfiguration.java

@Configuration
@PropertySource("classpath:foo.properties")
public class FooConfiguration { }

src/main/resources/foo.properties

spring.profiles.active=prod

src/main/resources/application.properties

# empty

console logs:

09:35:18.141 : No active profile set, falling back to default profiles: default
09:35:20.175 : prod

The profile is not considered during startup, but is available on the Environment after startup.

Question: How do I load properties from @PropertySource and make them available at startup at the same point the rest of the application.properties are loaded?

Zack
  • 3,819
  • 3
  • 27
  • 48
  • 1
    i think `@propertySource` is Class or bean specific `Given a file app.properties containing the key/value pair testbean.name=myTestBean, the following @Configuration class uses @PropertySource to contribute app.properties to the Environment's set of PropertySources.` – Ryuzaki L Jan 27 '19 at 16:10
  • @Deadpool not true, `@PropertySource` loads additional values into the `Environment`, see the javadoc explanation: `Annotation providing a convenient and declarative mechanism for adding a PropertySource to Spring's Environment. To be used in conjunction with @Configuration classes.` – Zack Jan 27 '19 at 16:12
  • 1
    okay then why don't you try adding this `PropertySource("classpath:foo.properties")` on main class and give a try? – Ryuzaki L Jan 27 '19 at 16:14
  • Classes annotated with `@SpringBootApplication` _are_ configuration classes. Adding `@PropertySource` is the same as adding it to a `@Configuration` annotated class. – Zack Jan 27 '19 at 16:17
  • 1
    @Zack, have you tried this in your application.properties: spring.config.location=file:foo.properties or classpath:foo.properties? – Faraz Jan 27 '19 at 16:25
  • Was actually just trying this, based on @santaatnas feedback. Adding it as a command line value works: `java -jar foo.jar --spring.config.location=classpath:/application.properties,classpath:foo.properties`, but not setting the same property in application.properties – Zack Jan 27 '19 at 16:29
  • I tried setting it in `META-INF/spring.factories` too – Zack Jan 27 '19 at 16:30
  • 1
    @Zack okay that was a wild guess by me. Nevermind. I delete that too as others who stumble upon it may find it confusing, And hence you have confirmed that it doesn't work, I gotto delete that comment. – Faraz Jan 27 '19 at 16:31
  • 1
    may this might give more info https://stackoverflow.com/questions/43020491/spring-boot-external-configuration-of-property-file#comment73131321_43021189 – Ryuzaki L Jan 27 '19 at 16:42

1 Answers1

2

I think you can use "--spring.config.location" property to specify what property file you want to use.

ipave
  • 1,249
  • 9
  • 17
  • Yes, but doesn't that only change where Spring finds the `application.properties` not necessarily the behavior of how additional property sources are loaded? – Zack Jan 27 '19 at 16:06
  • 1
    Yes, it specifies default property file, if you use @PropertySource all fields are overriden with according property source file. – ipave Jan 27 '19 at 16:11
  • Yes, that is fine -- that is the expected behavior. However, the `@PropertySource` will still not be considered at initial startup -- only at `Environment` loading, as per my initial example. – Zack Jan 27 '19 at 16:19
  • 1
    No it won't, as i said before if you want to use it at initial startup you should use "--spring.config.location" property, In which you can specify even both property files like this: --spring.config.location=classpath:/default.properties,classpath:/override.properties – ipave Jan 27 '19 at 16:23
  • This does work. Is there a way to set `spring.config.location` in a property file or `spring.factories` to avoid passing it as a vararg or setting a system property? – Zack Jan 27 '19 at 16:31
  • 2
    No you can't `spring.config.name and spring.config.location are used very early to determine which files have to be loaded, so they must be defined as an environment property (typically an OS environment variable, a system property, or a command-line argument).` – Ryuzaki L Jan 27 '19 at 16:32
  • 1
    https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-application-property-files @Zack – Ryuzaki L Jan 27 '19 at 16:33
  • Setting the `--spring.config.location` is probably the best answer then. Will leave this open for a bit in case any other ideas flow in. – Zack Jan 27 '19 at 16:43