Since my project has multiple environments and multiple small project groups, I need to handle the corresponding business logic according to different property names, but I can't find any parameter in bootstrap.yml that can set the custom configuration file path.
After I googled, I only found a way to modify the path of the custom configuration file through the startup class
Is there any other better way for me to configure it? Please help me!
Spring Boot look for your externalized configuration file in four predetermined
locations :
in classpath root,
in the package /config in classpath,
in the current directory
in /config subdirectory of the current directory.
i think you want to load configuration file from /config folder.
You can programmatically tell Spring Boot to load your configuration files from
custom location as below :
ConfigurableApplicationContext applicationContext = new SpringApplicationBuilder(Application.class)
.properties("spring.config.name:application,conf",
"spring.config.location:classpath:/your/location/of/config/folder,classpath:/another/location/of/congig/folder")
.build().run(args);
Related
Is there a way to import all configuration files in a directory without having to explicitly specify their profiles / filenames one by one?
I thought of using spring.config.import but it doesn't seem to support specifying a directory or pattern to dynamically import whatever configuration files are contained within the directory.
For example:
I have the main config application.yml and children config in the config/ directory, which contains application-test1.yml, application-testN.yml and so on. I want to automatically load all the config files under the directory without specifying them explicitly in application.yml.
I tried these below, but they don't work.
spring
config
import: classpath:config/
spring
config
file: file:config/*/
spring.config.location=classpath:/custom-config/
This should load the configuration from the specified folder. As per the different profiles configurations, only active profiles configuration would be imported, so you need to make sure that the standard configuration file that gets loaded activates these profiles (eg. using spring.profiles.include)
Further references:
https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-external-config-files
In my project I have seperate application.yml files for each environments, inside each folder for an environment.
NOTE: Below red color yml file made temporarily, to make the code work. But should remove this after fixing. So what I want is to use separate application.yml file according to environment. Specially I need to use local/application.yml for local development
Below has an example of getting env variables in my project
#Component
#Configuration
public class ApplicationProperties {
#Value("${ex.my.url}")
private String myServiceUrl;
// getters setters and nedded stuff
}
But it doesn't work, since could not find a way to mention the needed environment. Because it is in a seperate folder. All the other examples mention the way to get the yml file inside resource folder, without seperate folders.
Any fix for the issue?
in my projects, I specify a profile with the VM option :
-Dspring.profiles.active=local
Then I have a file named application-local.yml
in production :
-Dspring.profiles.active=prod , will use the file application-prod.yml
In the resources folder
Do make file of application.yml, application-local.yml, application-dev.yml etc.. what ever you want
and then in application.yml
spring.profile.active = ${ENV}
now during the run specify the ENV variables from run/debug configuration under Intellij or mention the profile for which you want to build the jar in application.yml.
Alternative, you can use the -D spring.profile.active=dev
at-first, from the documentation:
SpringApplication loads properties from application.properties files in the following locations and adds them to the Spring Environment:
A /config subdirectory of the current directory
The current directory
A classpath /config package
The classpath root
So, with passed directory hierarchy you'll get problems.
at-second, for file specification, you could use Profiles. This works as follows:
if no specified profiles - application.properties would be used
for any additional profile also would be used profile with name application-<name>.properties
Thus, if you specify dev and cool profiles, properties application.properties, application-dev.properties, `application-cool.properties, would be in use
UPDATE:
You could pass spring.config.location for property file path specify, but if you want directory hierarchy as you have - you need some customizations using context.initializers.classes and ApplicationContextInitializer
The classic solution is to setup one config file
(I prefer properties because I'm sane)
and allow for an overrides file to be placed on each installed host.
Spring supports this out-of-the-box.
Here is an example:
public static void main(final String[] argumentArray)
{
final StringApplicationBuilder springApplicationBuilder;
springApplicationBuilder = new SpringApplicationBuilder(YourSpringBootApplication.class)
springApplicationBuilder.properties(
"spring.config.location=classpath:/yourConfig.properties,/some/path/to/overrides/directory/yourConfig.properties");
springApplicationBuilder.build().run(argumentArray);
}
I'm not certain anymore about how Spring-boot exactly handles environment, properties file and config location.
Use case
Below the result docker container of my spring-boot application
Docker container
/
|- spring-boot-app.jar
|- /config/
|--|- application.properties
|--|- logback-spring.xml
I also use environment variables
The problem
The logback-spring.xml isn't read by Spring-boot.
To make it so I HAVE TO add LOGGING_CONFIG=config/logback-spring.xml
Shouldn't Spring-boot look for logback-spring.xml automatically under this directory ?
Thank you
In the Spring Documentation (https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-logging.html) it says:
The various logging systems can be activated by including the
appropriate libraries on the classpath, and further customized by
providing a suitable configuration file in the root of the classpath,
or in a location specified by the Spring Environment property
logging.config.
So if you put the file directly beneath spring-boot-app.jar it should work without configuration of logging.config.
Spring boot automatically loads application.properties and application.yaml from below locations, Values from lower-order overriding earlier ones
The classpath root
The classpath /config package
The current directory
The /config subdirectory in the current directory
Immediate child directories of the /config subdirectory
I am using #PropertySource in my datasource configuration file to get property files located on classpath. Below is my project structure.
I believe I can do it in two ways:
By creating a package in src folder and add them there. As src folder is already included in the classpath in eclipse, following should work.
#PropertySources({
#PropertySource("classpath: com/spring/property/general.properties"),
#PropertySource("classpath: com/spring/property/hibernate.properties")
})
Second way is to create a resources folder and add it to the classpath and following should work
#PropertySources({
#PropertySource("classpath: general.properties"),
#PropertySource("classpath: hibernate.properties")
})
In my case neither of the two is working. Being an intermediate java developer this still confuses me. Can anybody guide me in the right direction. And also how we can configure classpath resources for Spring in a production environment.
EDIT:
I have changed my project structure to include properties file in src/java/resources and I can see the resources folder in build path. Still .properties are not found by spring.
For anybody facing problem with usign .properties files in Spring 4+, look at the thread below to match your setup with that of OP. Setup is all good except for a whitespace in configuration.
Not able to inject .properties file into Spring MVC 4.3 using #PropertySource
We are using a spring boot application, where properties are loaded from application.yml file instead of application.properties, located at src/main/resources/ which looks like below:
config:
host: localhost:8080
server: 123
And they are being pulled in a .java file like this
#ConfigurationProperties( prefix="config")
public class ConnectionImpl implements Connection{
#Value("${config.host}")
private Stringhost;
}
I am able to retrieve properties this way.
But we are trying to move the config properties from application.yml to a different .yml file which is located at a different location. (src/main/resources/env-config).
Now I am not able to retrieve properties same way, i.e, using #Value annotation. Is there any other annotation I need to add ?
From the documentation:
SpringApplication will load properties from application.properties (or application.yml) files in the following locations and add them to the Spring Environment:
A /config subdirectory of the current directory.
The current directory
A classpath /config package
The class path root
If you don’t like application.properties as the configuration file name you can switch to another by specifying a spring.config.name environment property. You can also refer to an explicit location using the spring.config.location environment property (comma-separated list of directory locations, or file paths).
The default search path classpath:,classpath:/config,file:,file:config/ is always used, irrespective of the value of spring.config.location. This search path is ordered from lowest to highest precedence (file:config/ wins). If you do specify your own locations, they take precedence over all of the default locations and use the same lowest to highest precedence ordering. In that way you can set up default values for your application in application.properties (or whatever other basename you choose with spring.config.name) and override it at runtime with a different file, keeping the defaults.
You need to supply a command line argument that tells SpringApplication where specifically to look. If everything in resources/ is added to the classpath root, then your command line would look like:
java -jar myproject.jar --Dspring.config.location=classpath:/env-config/service-config.yml
If you have a general application.yml under resources/, the properties in there will still be loaded but will take a lower precedence to the properties file specified on the command line.
Your question doesn't really say what you intend to do, but if you want to have a different configuration for different environments (e.g. development, test, production), there is a simple solution for that.
Place your config files in a file hierarchy like this inside your project:
src/
main/
resources/
application.yml
application-development.yml
application-test.yml
application-production.yml
When you now start your application with
java -jar mySpringApplication.jar -Dspring.profiles.active=development
the configuration from application.yml will be taken as a "base layer", overridden by the configuration in application-development.yml. By this, you can have "default" settings for all environments in application.yml and environment-specific configuration in the application-ENV.yml files. The same works for test and production.
No.
You'll be in a much better position if you avoid hard-coding file path like that within your code base. #ConfigurationProperties used to have a locations attribute but it's deprecated and already removed in 1.5.
In Spring Boot, you configure the Environment which is a single source of truth for your configuration. Rather than having settings buried in code, you should configure Spring Boot to read the files that you want. Read the documentation for spring.config.location. If you want to do this in a more transparent manner, perhaps EnvironmentPostProcessor is what you need