Library (JAR) default value for properties spring - java

I have an application that need to send emails. I might need later to send emails in a second application so I try to do a library to re-use it.
My application is done with Spring-boot.
My library just include Spring-core, Spring-context and Spring-test.
This is my EmailUtils in my library :
#Named
public class EmailUtils {
#Value("${from}")
private String from;
#Value("${to}")
private String to;
...
}
I would like to have a default file application.properties with that in the library :
from=default-from
to=default-to
now I would like if my application spring boot does something like that :
#Service
public void EmailService {
#Inject
private EmailUtils emailUtils;
...
}
I would like if I don't define a new application.properties in my application to get the default value from the library but would be possible to override them by using an application.properties in my Spring-boot app.
Info : My Spring-boot app have ScanComponent package (just to mention it). But my library has nothing. I don't know if I have to use a beans.xml and define a ContextPlaceHolder ...
I am a little bit loss, maybe there is a better way to do it ?
Thank you.

If I am correctly understanding your question - you want to specify a default value for your #Value annotated properties. You can do this simply by simply using the format #Value("${property_key:default value}") so if you wished the default from value to be me#me.com and to to be you#you.com your code would read:
#Named
public class EmailUtils {
#Value("${from:me#me.com}")
private String from;
#Value("${to:you#you.com}")
private String to;
...
}

Related

SPring Boot external Jar config injection

I have spring boot application which is referring to Framework jar( Framework jar are common library jar's which are required by all microservices )
In framework jar i have used #Value annotation to read the config.
#Value("${isxyzFeatureEnabled}")
private static String isFeatureEnabled;
This value is not getting set when the application starts. However if i move this class to Individual microservice then it works.
I need to keep this class in framework as it will be reused by many microservices.
Any suggestions how can i resolve this.
Your variable is static.
Unfortunately, "Spring doesn't support #Value on static fields."
Try this solution:
#RestController
public class PropertyController {
#Value("${name}")
private String name;
private static String NAME_STATIC;
#Value("${name}")
public void setNameStatic(String name){
PropertyController.NAME_STATIC = name;
}
}
More info about that: https://www.baeldung.com/spring-inject-static-field

ConfigProperty not injecting the value into the field

I am new to quarkus environment. I have a quarkus application where I'm trying to inject the property config using
org.eclipse.microprofile.config.inject.ConfigProperty
Here is the sample code
public class Temp {
#ConfigProperty(name = "secret.token")
static String SECRET_KEY;
public void display() {
System.out.println(SECRET_KEY);
}
}
Here is the content of my application.properties
secret.token = ${TOKEN_SECRET:Root}
Here display method is always printing null.
The thing is the same property is being injected into the controller/resource endpoint classes properly but not in this class. I also tried using #Inject along with #ConfigProperty but no luck. Any pointers would really help.
The class on which the annotation is used, needs to be a CDI bean.
The easiest way to accomplish that is to annotate the class with #Singleton and use with something like #Inject Temp temp wherever the class is used.
See https://quarkus.io/guides/cdi for an intro to CDI

Spring Cloud Config: Call a bean from bootstrap.properties/yml

Is it possible to call a bean from bootstrap.properties?
I'm trying to implement a Cloud Config Client.
The Bean is similar to:
#Bean
public MyObject myObject(String environment) {
return new MyObject(environment);
}
....
public class MyObject {
private String environment;
// getters setters
}
In the bootstrap.properties file I have the following line:
spring.profiles.active= #Here I should get the value from the bean
Is it possible to write something like:
spring.profiles.active= ${myObject.environment}
Thank you very much.
You can, plugging into spring.factories:
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
com.demo.MyBootstrapConfiguration
And then write a normal Spring Java Configuration Object
#Configuration
public class MyBootstrapConfiguration {
// normal spring java config
}
Based on the docs, the bootstrap file:
Out of the box it is responsible for loading configuration properties
from the external sources, and also decrypting properties in the local
external configuration files
and the its content is meant to be referenced in the beans, not the other way round.
If you want to pass the active profile somehow to it, based on the docs you can:
1) Use -D option while starting the app:
java -jar -Dspring.profiles.active=production demo-0.0.1-SNAPSHOT.jar
2) Set SPRING_PROFILES_ACTIVE property on your OS environment.

What's the Spring way of accessing properties from an entity?

I'm new to Spring and I'm building an application where some entities (JPA/Hibernate) need access to a property from application.properties. I do have a configuration class in which this is trivial:
#Configuration
public class FactoryBeanAppConfig {
#Value("${aws.accessKeyId}")
private String awsAccessKeyId;
#Value("${aws.secretKey}")
private String awsSecretKey;
}
but since entities do not have and I think they should not have the annotations such as #Configuration or #Component, what's the Spring way for them to access the property?
Now, I know I can create my own class, my own bean, and make it as a simple wrapper around the properties; but is that the Spring way to do it or is there another way?
specify Property file location using #PropertySource
Something like below
#PropertySource("classpath:/application.proerties")
You also need to add below bean in your config
#Bean
public static PropertySourcesPlaceholderConfigurer propertyConfigIn() {
return new PropertySourcesPlaceholderConfigurer();
}
There is no "Spring way", since JPA entities and Spring have nothing to do with each other. Most importantly, JPA entities are not Spring beans, so Spring doesn't know or care about them as they're not managed by Spring.
You can try to hack around, trying in vain to access Spring's configuration from code that should not be trying to access it, or you can accept the truth that your design is broken and you're trying to do something that's not meant to be done.
As was proposed several times, use a service class for this. It's managed by Spring, so it can access the Spring config, and it can handle entities, so there's no crossing boundaries.
First create a public static variable in some bean managed by Spring, then make the following use of the #Value annotation.
public static String variable;
#Value("${variable}")
private void setVariable(String value) {
variable = value;
}
It will be set at runtime on startup, now you can access it from entities and everywhere else because it is just a public static var.
You can use #PropertySource to load the properties file as follows
#Configuration
#PropertySource("classpath:/com/organization/config/application.proerties")
public class FactoryBeanAppConfig {
...
}
Entities should not acces environment properties. If you are using your entity through a service, then the service can access the properties to act on the entity.

Spring Environment Variable

I was planning to use #Value annotation to my service implementation class.
#Value("${some_property:default_value}")
private String key;
To use above annotation, I can use #Autowiredannotation.
#Autowird
Private Environment environment;
But, I am planning to use those setting in my applicationContext.xml file, which is something like following below.
<context: something missing here = "ENVIRONMENT"/>
Yes. You can do it in applicationContext.xml beans tag itself there is a property called profile So you can do profile="ENVIRONMENT" in latest spring version.

Categories