Is it possible to have a profile in spring boot and also another profile that inherits most of the parent values and beans?
For example I have two profiles
staging and staging-task.
I want staging-task to inherit the database configuration of the staging profile however I want it to override the jpa configuration.
Is profile inheritance available to #Configuration beans.
Yes. Its possible to have spring profiles in spring boot.
For your problem, put your common database configuration in application.yml(default profile).
And you can override the other properties in application-stage.yml.
Spring will read the properties from application.yml and override from application-stage.yml when active profile is stage.
TL;DR
The active profiles will cause respective application-$profile.properties to be read (if they exist) in the order the active profiles are defined. Later read properties override earlier ones. That will give you the means to do smth. like an hierarchy.
Long Version
There is no such thing as profile-inheritance in spring but it can be mimicked as written in the answer by JRR.
For how it actually works read: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-profile-specific-properties.
Related
I'm new to spring and I'm studying it. And stumbled upon the #Profile annotation.
I want to write a simple project with Spring (not Springboot) to learn how to load properties based on the environment using #profile annotation. Almost everywhere, the examples (Ex1, Ex2) I see only with the Springboot. I'm wondering whether we cannot write a Spring application that can dynamically load the properties based on the environment (dev, prod).
Some examples ( Ex3, Ex4, Ex5) show with the #Profile but those have hardcoded the bean details for each environment like below. Is this how we have to write the property loading?
#Profile("dev")
#Bean
public String devDBCcnnection() {
System.out.println(dbConfiguration.getUrl());
return "DB Connection for Dev";
}
#Profile("test")
#Bean
public String devTestCcnnection() {
System.out.println(dbConfiguration.getDriverClassName());
return "DB Connection for Test";
}
#Profile("prod")
#Bean
public String devProdCcnnection() {
System.out.println("DB Connection for Prod");
return "DB Connection for Prod";
}
It has to write a bean for each profile like in the above example?
Can someone tell me using #Profiles, can't dynamically load the property values like in Spring applications?
Appreciate it if you can give the samples with Spring 5
Almost everywhere, the examples (Ex1, Ex2) I see only with the
Springboot. I'm wondering whether we cannot write a Spring application
that can dynamically load the properties based on the environment
(dev, prod).
Spring boot uses the spring context. The spring context allows you to use profiles. Therefore no problem using profiles with simple Spring project (non spring-boot).
There are many ways that you can use Profiles.
One of them is the example that you gave with specific beans that have #Profile and get registered in spring for a specific profile.
Another one, more commonly used in enteprise applications is to ship a jar application with multiple application.yaml files. So for example you ship your application, containing dev-application.yaml and qa-application.yaml. You can then start your application selecting a specific profile to be active. Then that specific application.yaml will be used when the application starts up to build the spring context. So the aplication will be started with qa-application.yaml and will have a connection to the QA database.
But be careful the default application.yaml will also be loaded. The specific application.yaml for example qa-application.yaml will be loaded on top of default application.yaml.
The following article contains very good information about spring profiles
spring profiles article
Considering my example here, I quotte something relevant from that article.
The Default Profile The default profile is always active. Spring Boot
loads all properties in application.yml into the default profile. We
could rename the configuration file to application-default.yml and it
would work the same.
Other profiles will always be evaluated on top of the default profile.
This means that if a property is defined in the default profile, but
not in the qa profile, the property value will be populated from the
default profile. This is very handy for defining default values that
are valid across all profiles.
In order to activate a specific profile
For non spring-boot projects here is a very good answer spring active profile
For spring-boot projects you can
Use a system variable to start your jar file
java -Dspring.profiles.active=qa -jar myApp.jar
Use an environment property to start your jar file
export SPRING_PROFILES_ACTIVE=qa
java -jar myApp.jar
Is there any way to load the respective hibernate config based on the property configured in a properties file.
I have an application to connect to Any database with the same schema through hibernate configs. Right now, I have created two hibernate configs One for DynamoDB another for all hibernate supported SQL's
I wanted to load only respective config by ignoring other config's.
i think we can specify like below
#Profile("prod")
#Configuration
Is it possible to create another property like profile.
There can be multiple profiles active at the same time in your application.
So you can have profiles for specific databases along with the profiles responsible for environment type.
Then, you can define your properties in files called application-dynamodb.properties and application-other.properties
Yes you can use #profile concept here.You can maintain multiple properties file with different configuration and activate that specific configurations for example by adding
spring.profiles.active=dev in application.properties, if application-dev.properties contains the required db configurations.But then you need to add #profile("dev") in configuration class while you are initializing/creating DB connection working with profile
Is it possible to use Spring Boot so that all configurations are explicitly in the main class?
For example, is it possible to tell spring-boot to print all autoconfigurations make by #SpringBootApplication so that I can copy paste in my main class?
Or is it possible to copy then from somewhere into the main?
You can have Spring Boot create a report (a list of auto configurations) simply by enabling debug mode in your application.properties file:
debug = true
The auto-configuration report contains information about the classes that Spring Boot found on the classpath and configured automatically. It also shows information about classes that are known to Spring Boot but were not found on the classpath.
And, because you've set debug=true in application.properties or application.yml, so you will see it in your output.
There is no way of doing this. Either you embrace the devil and suffer the consequences latter if you need to personalize something unpredictable by spring boot developers or you don't use it's magic.
I want to add a custom property to the application.yml of my Cloud Config. The comments in the file say it is for all shared configuration. However, when I do so, it causes the binding of the properties to JHipsters own ApplicationProperties to fail at the class does not have the correct writable property.
application.yml
application:
clients:
- Foo
Stacktrace:
Caused by: org.springframework.boot.bind.RelaxedBindingNotWritablePropertyException: Failed to bind 'application.clients[0]' from 'file:central-config/localhost-config/application.yml' to 'clients[0]' property on 'io.github.jhipster.registry.config.ApplicationProperties'
From JHipster's documentation:
Application-specific properties Your generated application can also
have its own Spring Boot properties. This is highly recommended, as it
allows type-safe configuration of the application, as well as
auto-completion and documentation within an IDE.
JHipster has generated a ApplicationProperties class in the config
package, which is already preconfigured, and it is already documented
at the bottom the application.yml, application-dev.yml and
application-prod.yml files. All you need to do is code your own
specific properties. (emphasis mine)
Have you done that step and added your own properties to ApplicationProperties.java? It looks like you should have a property of type List<String> clients. If you haven't that's why it's failing, because it's attempting to bind a configuration property to the ApplicationProperties class, but the class doesn't contain a property to store it.
Custom Spring boot properties should always be defined in a #ConfigurationProperties class within the app so that their value can be setup in the yml file. This is thoroughly documented in the spring boot documentation:
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
I have a spring file config1.xml that has beans with no explicitly defined profile. I also have another file config2.xml with two bean profiles (profileA and profileB). If I import the latter one into the former and activate profileA at runtime, would the beans in config1.xml be activated? If not, is there a way to do this without replicating the code for config1.xml?
Yes, they will be activated. By default your beans have no profile and are loaded into the container. Only if you specify profiles for the beans explicitly, they will be bypassed unless one or more of the specified profiles are active.