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
Related
I am developing a library with a Spring framework and adding as a dependent for different frameworks. Does Spring framework #Value annotation inside library work for different frameworks that take application properties from other frameworks and also from spring boot too? Or do I have to use pure Java with a resource bundle?
Spring-Boot library:
#EnableAutoConfiguration
#Configuration
public class ClientProperties {
#Value("${application.url:#{null}}")
public String baseApplicationUrl;
public static String application_url;
#Value("${application.username:#{null}}")
public String platformUsername;
public static String username;
#Value("${application.password:#{null}}")
public String platformPassword;
public static String password;
A client application using a different framework that is not spring. Application properties file as follow:
application.url="localhost"
application.username=test
application.password=test
I have a Spring Config class which I want to have it loaded when the application is running.
#Configuration
public class EventHubConfiguration {
#Bean
#ConfigurationProperties(...)
public EventHubClient someClient(final String namespace,
final String eventHubName,
final String sasKeyName,
final String sasKey) throws IOException, EventHubException {
ConnectionStringBuilder connStr = new ConnectionStringBuilder()
.setNamespaceName(namespace)
.setEventHubName(eventHubName)
.setSasKeyName(sasKeyName)
.setSasKey(sasKey);
return EventHubClient.createSync(connStr.toString(), Executors.newSingleThreadScheduledExecutor());
}
}
But how can I prevent it from loading when my integration tests are running. For example when I do mvn clean test or as part of my build. I don't wish the eventhub client to be created during my integration testing.
As i see in spring doc :
https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#integration-testing
3.2.2. Dependency Injection of Test Fixtures
When the TestContext framework loads your application context, it can optionally configure instances of your test classes by using Dependency Injection. This provides a convenient mechanism for setting up test fixtures by using preconfigured beans from your application context.
So yes your test class must be a bean
I am trying to write a scanner for custom annotations based on the answer in Scanning Java annotations at runtime.
However, to speed up the process, I only want to scan the classes under the main package (package which has the main class and its sub-packages). Figured that the easiest way to determine the package name would be from the main class.
The code I am writing would end up in a library which will be used by Spring Boot applications. So I have no way of knowing the name of the main class. Is there a way to determine the name of the main class at runtime in Spring Boot application?
Regards,
Anoop
Assuming your main class is annotated with #SpringBootApplication, it can be done using ApplicationContext::getBeansWithAnnotation():
#Service
public class MainClassFinder {
#Autowired
private ApplicationContext context;
public String findBootClass() {
Map<String, Object> annotatedBeans = context.getBeansWithAnnotation(SpringBootApplication.class);
return annotatedBeans.isEmpty() ? null : annotatedBeans.values().toArray()[0].getClass().getName();
}
}
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.
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;
...
}