Spring: How to provide a specific property file in the #Scheduled annotation? - spring

Normally, we can use a cron expression defined as "cron.expression" in the default property file, as follows:
#Scheduled(cron = "${cron.expression}")
public void demoServiceMethod(){
}
But I wish to define a property file for this class itself, and use the "cron.expression" property from this file. How can I do that?
P.S: I am using Java 1.7

Add to your class PropertySource
#PropertySource("classpath:other.properties")
Or using Configuration
#Configuration
#PropertySources(value = {#PropertySource("classpath:/datasource.properties")})

Related

#Value annotation is only loading default - not using property file

Problem
I think that I havn't understood something properly because my #Value is always loading the default calue.
Java Code
So I have the following:
#Value("${disableQuerySecurityDebug:false}")
private boolean disableQuerySecurityDebug;
And this is set to false always.
Property file: application-disableQuerySecurityDebug.properties
I have a properties file called application-disableQuerySecurityDebug.properties.
And I have the following entry inside the file:
disableQuerySecurityDebugMne=true
And I run the application with the following profile: disableQuerySecurityDebugMne
I was expecting the value to be set to true, but it is always false.
Update
Based on deadpool's answer, I ended up with the following:
#Profile("disableQuerySecurityDebug") #Data
#Configuration
public class DisableSecurityConfig implements DisableQuerySecurityDebug {
#Value("${disableQuerySecurityDebug:true}")
private boolean securityDisabled;
}
#Profile("!disableQuerySecurityDebug") #Data
#Configuration
public class EnableSecurityConfig implements DisableQuerySecurityDebug{
#Value("${disableQuerySecurityDebug:false}")
private boolean securityDisabled;
}
public interface DisableQuerySecurityDebug{
public boolean isSecurityDisabled();
}
#Value annotation is only used to inject properties values into spring Beans from yml or properties file
This annotation can be used for injecting values into fields in Spring-managed beans and it can be applied at the field or constructor/method parameter level.
If you want to inject values based on profile specific then use #Profile on class
#Profile("disableQuerySecurityDebug")
#Configuration
public class Config {
#Value("${disableQuerySecurityDebug:false}")
private boolean disableQuerySecurityDebug;
}
You could also specify it on the command line by using the following switch:
java -jar demo.jar --spring.profiles.active=disableQuerySecurityDebug

Can you or can't you use a property from a config file when using Spring #Condition?

I have read pretty much everything I can find on StackOverflow and other sites and I don't see a definitive answer anywhere.
I have a class that implements #Condition that I use in a #Configuration file to conditionally load some beans. I am doing something like this:
public class MyCondition implements Condition {
#Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metdata) {
String property = context.getEnvironment().getProperty("some.prop.from.file");
boolean enable = Boolean.parseBoolean(property);
return enable;
}
}
When debugging I see that getting the property from the environment always returns null, even though the property is injected in other beans using #Value.
So my question can you or can't you attempt to get a property value from a file within a #Condition class? Can you only get System properties? I would think that this is a common use case that I would think Spring could handle.
Had to add the property to application.properties and not the other property files that are loaded during startup.

how to apply user defined properties value to #RequestMapping

I have several #RequestMapping which value will subject to change from "/XXX" to "/V100" on someday. So I need to define it in properties. I've googled and there's way using application.properties but I have to keep "/XXX" value in a user defined properties like a "local.properties". Is it possible to define #RequestMapping value on a user defined properties?
#Controller
#RequestMapping("/XXX")
public class MyController {
...
}
** UPDATE : tried several hours and get it to work.
my.properties
api.version=V100
mvc-context.xml
<context:property-placeholder ignore-unresolvable="true" location="/WEB-INF/config/property/my.properties"/>
controller
#RequestMapping("/${api.version}")
tomcat log
localhost-startStop-1> [2016-04-28 15:01:35.410] [INFO] [RequestMappingHandlerMapping] [534] Mapped "{[/V100/detail],methods=[GET]}"...
In addition to the xml solution provided by #JustinB, here is an annotation-only solution (tested with Spring Boot):
#Controller
#PropertySource(value = "classpath:/user.properties", ignoreResourceNotFound = true)
#RequestMapping("/${api.version:}")
public class MyController {
...
}
The value of api.version is read from If src/main/resources/user.properties if it exists. If the file is missing or api.version is not set, it will default to an empty string.
Beware, if api.version is also defined in application.properties it will take precedence whether or not user.properties exists and api.version is set in it.
More examples of #PropertySource are provided here.

What configuration enables the evaluation of #Value annotations?

I'm tying to do a very minimal programmatic/annotation based configuration of Spring, to do some command line stuff and I want to be able to inject value of some bean values from System properties.
I'm using the #Value like this:
#Value("${MigrateDb.task:default}")
private String task;
It's sort of working, but it's not evaluating the value definition, I'm just getting "${MigrateDb.task:default}" in the actual field, instead of Spring evaluating it and giving me the value of the Migrate.db.task system property (or default).
What do I need to add to my Configuration class to enable this behaviour?
try using it this way:
#Value("${MigrateDb.task:default}")
private String task;
XML Config:
<context:property-placeholder
location="your.filelocation.properties" />`
Java Config :
#Bean
public static PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() {
PropertyPlaceholderConfigurer propertyPlaceholderConfigurer = new PropertyPlaceholderConfigurer();
propertyPlaceholderConfigurer.setLocation(new ClassPathResource("file.properties"));
return propertyPlaceholderConfigurer;
}
From ShadowRay's answer, the minimum code to enable the requested behaviour is:
#Bean
public static PropertyPlaceholderConfigurer propertyPlaceholderConfigurer(){
return new PropertyPlaceholderConfigurer();
}
Method should be static as per: https://stackoverflow.com/a/14943106/924597

Inject #Scheduled fixedRate value from Spring Boot application.yml file

I know I can inject the value from properties file with the following syntax:
#Scheduled(fixedRate=${myRate})
public void getSchedule(){
System.out.println("in scheduled job");
}
However I can't guess how to accomplish the same if the configuration is in YAML file.
Thanks in advance,
In my application.properties (YAML) I put this
console:
fetchMetrics: 5000
Then in my simple Task class I push the definition :
#Scheduled(fixedRateString ="${console.fetchMetrics}", initialDelay=1000)
public void fetchMetrics() {
logger.info("What's up ?");
}
Please notice that fixedRate expects a long and you want to inject a placeholder, you will need fixedRateString
I find it easy once done for my project.
Change fixedRate to fixedRateString and put the property key in double quotes like this:
#Scheduled(fixedRateString="${myRate}")
public void getSchedule() {
System.out.println("Scheduled job");
}
In my application I use the annotation PropertySource on my config class:
#PropertySource("application-${spring.profiles.active}.yml")
spring.profiles.active returns the active profile (dev, test, etc). My properties file name is application-dev.yml
The annotation #Scheduled works with property injection.
Dont forget the annotation with prefix configuration on your class.

Resources