In Spring is it good practice to put custom properties into the default application.properties/yaml file? - spring

I have a Spring Boot application. I want to add some custom properties.
Is it good practice to put these properties into the default application.properties/application.yaml file?
Or is it better to put them in a new properties file and keep only Spring properties in application.properties/application.yaml?

If you aren't using too many Spring properties, that someone might miss your custom properties, you can use the default one. It isn't a bad practice to do so.

Related

Why spring.jpa.properties. prefix is not always required in Spring Boot properties

I learning Spring boot and found that in some examples use the same properties with the prefix spring.jpa.properties while other do it without prefix.
For instance:
The article explains second level cahche https://www.baeldung.com/hibernate-second-level-cache and autor shows example of needed properties ( example on autor's gitHub):
hibernate.cache.use_second_level_cache=true
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
But it did not work for me, and I spent few hours loking for the reason, but then i noticed, someone use prefix spring.jpa.properties. to get it working (Exact moment from video lesson):
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
Which perfectly worked for me.
So my questions are:
why are they working in different way?
how to understand which properties in which cases requires this prefix?
is it probably something related to my project settings OR Spring Boot version?
any other suggestions are appreciated :)
Thank you in advance!
There are a couple of things in play here. First the tutorial you use is using plain Spring not Spring Boot. Which means a manually configured EntityManagerFactory on which you directly can set the provider specific properties. Like hibernate.cache.use_second_level_cache.
As you decided to use Spring Boot you don't have a manually configured EntityManagerFactory (although you could!). Which means you are using an autoconfigured EntityManagerFactory. Properties for this reside in the spring.jpa namespace for properties.
As it isn't feasible to specify properties for each and every extension for Hibernate (or other JPA providers) only some commonly used ones are exposed like spring.jpa.generate-ddl and a few provider specific ones in the spring.jpa.hibernate namespace. However to set all the other properties in an autoconfigured way there needed to be something else. Hence the spring.jpa.properties prefix. Anything specified in there will be passed on as is (without the said prefix ofcourse) to the EntityManagerFactory for configuration.

Any way to split Spring Boot configuration into multiple properties files without having to specify an environment variable/system property

New to Spring Boot here, long-time Spring Framework user though.
I'm looking for a way to split my externalised configuration into multiple .properties files, for better readability and manageability.
I already saw this SO answer: having the ability to specify a list of configuration file names in spring.config.name (which, by the way, doesn't seem to be mentioned in Boot reference documentation, correct me if I'm wrong) would solve my problem perfectly, however that configuration property can be specified only via system properties or environment variables. If I try to specify it inside my application.properties file, it gets ignored. The same happens for spring.config.additional-location. I understand this happens because, when application.properties is read, it's too late to tell Spring Boot to search for different externalised configuration file names. However this is not a proper solution, because the way I split my configuration should be an "implementation detail" that the consumer of my application shouldn't be aware of, so I don't expect the consumer to specify an external parameter otherwise my application breaks out-of-the-box.
I think that a way to do this should be provided. Perhaps some import mechanism for .properties files or the ability to specify spring.config.name even in application.properties (some known and reasonable limitations would be acceptable).
The best I could find out is to use #PropertySource, but this is not profile aware: unless you use some ugly nested class hack, or you put spring.profiles.active variable in the resource name (which will break if multiple profiles have been activated), you won't get the benefit you have for application.properties profile-specific files.
I was not able to find an "official way" to do this, apart from some statements from Spring Boot devs that say that they're rather promoting the use of a single (possibly giant...) externalised configuration file. It seems like this position is not so popular, judging from the post reactions on GitHub, and IMHO it really seems to be a basic feature missing. I have been working with multiple properties files in Spring Framework (using XML configuration) for years and I never felt that having an only huge file would have been better.
If I understand it right, in Boot 1.x this was in some way possible using the location attribute of #ConfigurationProperties, which is however missing in Boot 2.x.
Any suggestion?
Have you tried with Spring Profile?
What you can do is create application-file1.properties/yml, application-file2.properties/yml and put it in config location and then add spring.profile.active=<your env profiles>,file1,file2.
It will load the files.
This profile entry can be in bootstrap.yml, or JVM args to application, in Manifest-<env>.yml in case of Pivotal Cloud Foundry. Not sure on AWS and other cloud provider.
Hope this will help.

Is there a way to generate application properties when creating a Spring Boot project?

I'm planning to run our own Spring Initializr instance. Is there a way to have a set of application properties get written (to application.yml) when a certain option is chosen, ideally in a separate section for each of a set of predefined profiles? I've looked into customising the project-generation process in Initializr and at creating a custom starter. I've come across auto-configuration for starters, but that seems to be about what configuration to default to when this has not been provided by properties, whereas I am after generating the properties. I've also come across an example of a custom Spring Initializr instance generating files, but I need it to modify application.yml without clobbering any other modifications that may have been made to it.
Spring Initializr (the library behind start.spring.io) does not have yaml support and does not allow you to write such file automatically when the project is generated.
It's easy enough for you to add that feature though. The way it works is through a model that contributors would tune + a writer that transform the model into the target output. An analogy of this would be MavenBuild and MavenBuildWriter that generates Maven's pom.xml.
Auto-configuration is indeed completely unrelated to code/configuration generation so no need to look there.

How can I directly add properties from a Spring Boot property source to the environment

I have a Spring Boot property source file containing a set of arbitrary properties. I would like to get all of those properties and add them to the environment.
I tried injecting the Environment into the class, and I am able to use that to get known properties. But I am not sure how to get all properties from there.'
If course I can use a traditional Properties.load() but is there a Spring way to do that?
Have you tried #PropertySource anotation?
I wouldn't recommend using PropertySource because you can't configure the precedence of the properties that you add. You may want that these properties can be overridden in some way, maybe? Or you may want that these properties take precedence over others. For this, I recommend you implement an EnvironmentPostProcessor.
There is a sample in this university session at Devoxx where we showcase how to read a file from the home directory and add it after command line properties. You could do pretty much the same thing and order them the way you want.
The sample app is available here if you want to give that a try.
If you put your properties into the "application.properties" (or any of the other places described here), the properties are automatically available in Spring's Environment.
One way to access the properties then is simply to #Autowire the Environment into the class where you want to access it.

Creating a PropertyOverrideConfigurer that takes values from the Database

Currently we have a PropertyOverrideConfigurer from Spring that is used to override some values of our configuration, the configuration is then used in Spring and Seam. Now I'd like to create an OverrideConfigurer that uses a DB connection managed by Seam to inject the overridden values into the configuration.
Is there already such a class or am I on my own?
I see that there is no support from Spring. Probably you need to do it yourself. This link may help you to confirm that you need do it yourself.

Resources