How to add properties programmatically(just like adding key-value into application.properties)? - spring-boot

I have some common properties that every projects should set, such as
feign.hystrix.enabled=false
feign.httpclient.enabled=true
I don't want to repeatedly add these props in every project so I'm going to create an extra jar file containing #Configruation class. How to add properties in #Configuration class? Thanks!

PropertySources
You may load an application.properties from another jar this way:
#PropertySources({
#PropertySource("classpath:common.properties")
})
#Configuration
public class SomeJavaConfig {
}
You can find the reference in Spring's documentation:
Spring Boot uses a very particular PropertySource order that is
designed to allow sensible overriding of values. Properties are
considered in the following order:
...
#PropertySource annotations on your #Configuration classes.
Spring-cloud-config
I won't go in all the details, but another option is to use spring-cloud-config to define these properties in a git (using spring-cloud-config-server). Then, have your spring-boot application load the application.properties using spring-cloud-config-client directly from git.
Check this:
https://cloud.spring.io/spring-cloud-config/spring-cloud-config.html
https://spring.io/guides/gs/centralized-configuration/

Related

Conflict with config class in dependency (Spring AsyncConfig)

My team uses some starter code that's included in every internal Spring project by default. This is included as a dependency (not parent) in the pom.xml file of my project. This starter code contains a default implementation of a configuration interface which Spring does not allow duplicates of (AsyncConfigurer), but I need to create my own custom implementation. I am not sure how to resolve this. Is there a way for me to exclude this configuration class but keep the rest of the dependency? Or can I somehow keep the given config class, but modify its properties?
The specific exception I get is: java.lang.IllegalStateException: Only one AsyncConfigurer may exist
//Thank you
You can define the AsyncConfigurer on parameter excludes from #SpringBootApplication. Example:
#SpringBootApplication(exclude=AsyncConfigurer.class)
Notice that this will excludes the entire #Configuration .
Another solution is to use bean override, to define only the beans you need to replace.
Add this to your application.properties (or yaml):
spring.main.allow-bean-definition-overriding=true
And you will be able to override it.

Spring Profile Use For Same Bean

Hi I am little bit confusign about using profiles in spring.My Scenario is I have a custom properties file.And It is values changes for each environment(dev,test,prod).I use same bean for each environment.But I want to change values for each environments.
In this property files all keys are same,only their values different.
mydev.properties
mytest.properties
myprod.properties
So How should I implement profile logic to my code in my scenario(Bean is same ,values are different)
//Here is my bean
#Component
#PropertySource("my.properties")
#ConfigurationProperties(prefix = "my")
public class MyProperties
{
....
I will add to 'spring.profiles.active' to my propertysource and is this enough?
//I plan to add spring.profiles.active
#Component
#PropertySource("my${spring.profiles.active}.properties")
#ConfigurationProperties(prefix = "my")
public class MyProperties
{
....
Please go through the Spring Boot Reference : Section 2.4. Profile-specific Properties
In addition to application.properties files, profile-specific
properties can also be defined by using the following naming
convention: application-{profile}.properties.
One need to define the profile specific properties in application-{profile}.properties
and declare the active profile
You can use a spring.profiles.active Environment property to specify
which profiles are active.
To answer your concern , the property value for the current active profile will be wired to the bean. Also note that
Profile-specific properties are loaded from the same locations as
standard application.properties, with profile-specific files always
overriding the non-specific ones, whether or not the profile-specific
files are inside or outside your packaged jar.
If several profiles are specified, a last-wins strategy applies. For
example, profiles specified by the spring.profiles.active property are
added after those configured through the SpringApplication API and
therefore take precedence.
In your case , the ideal way to define profile specific properties would be
application-dev.properties
application-test.properties
application-prod.properties

Load active properties file spring boot

I want to read values from an active profile or can say active properties file.
I have three properties files
application-dev.properties
application-stage.properties
application-prod.properties
I have set an active profile to dev as follows
spring.profiles.active=dev
My application-dev.properties file has one entry that i want to read in my class.
application-dev.properties file
fix.connection.type=initiator
I tried reading this entry
#Configuration
#PropertySource("classpath:application-${spring.profiles.active}.properties")
#Component
public class AdaptorDestination {
#Value("${fix.connection.type}")
private String connectionType;
}
Exception
nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'spring.profiles.active' in value "classpath:application-${spring.profiles.active}.properties"
Please help me out
You don't need to use #PropertySource annotation in order to load a property using #Value annotation.
Spring will load #Value property automatically from the current active profile.
Also, you don't need to specify ${spring.profiles.active} in the #PropertySource annotation as Spring always loads properties from the currently active profile by default.
Spring automatically resolves file name based on the profile suffix.
So you need only specify the base filename, e.g.:
#PropertySource("classpath:application.properties")
If the currently active profile is "dev" Spring will load properties at first from application.properties file and then override them with properties from application-dev.properties file.
You can read more here
You can use the annotation #Profile("profile-name") to determinate when to execute the method.
Spring Profiles

spring boot setting up message.properties and errors.properties file in the project structure and reading file to code

I am new to spring boot. I want to add external properties files in project structure . Files are errors.properties, messages.propeties and sql.properties file which contains the all sql queries. I get it where to add it i.e \demo\src\main\resources\errors.properties file. Can Anyone of you give me insight how to read from these files to my java code .
The easiest way would be to leverage what Spring Boot already give you automatically. Anything you put into application.properties (under \demo\src\main\resources) is going to be added to your Environment. I would just take the keys from those three files and create unique entries in application.properites
errors.key1=value1
errors.key2=value2
sql.key1=value1
....
Then you can use the #ConfigurationProperties annotation to map those configurations to a class that encapsulates each type.
#Component
#ConfigurationProperties(prefix="errors")
public class ErrorSettings {
private String key1;
.....
//getter and setters
}
Now you have a Bean of type ErrorSettings that you can inject into any other Bean you declare and just call the getXXX() method of the configuration you want.
Reference doc:
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

Spring Java config: import properties file

How to import a properties file and access a property while using Java configuration to configure Spring.
I want to do all in java. Is there a way to do it?
I tried to use #ImportResource("classpath:config.properties") but did not work.
I've done this on my #Configuration class using:
#PropertySource(value="classpath:application.properties")
You can get the properties in number a number of ways:
Inject Environment into configuration beans that need the properties and use environment.getProperty("my.property.value"), or
Annotate a property with #Value as outlined here.

Resources