Accessing user defined properties using spring expression language - spring

Is it poosible to read user defined .properties file using SpEL? I know we can do something like this for systemProperties
#Value("#{ systemProperties['user.region'] }")
I want to access a property in a user defined properties file. Also is it possible to use SpEL in #ContextConfiguration annotation? I want to set the value of this annotation using a properties file defined by me.

Yes, you can do:
private #Value("${propertyName}") String propertyField;
And you will need PropertyPlaceholderConfigurer
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
p:location="classpath:myProps.properties" />
or with java config
#PropertySource("classpath:myProps.properties")
on the config class

Yes, you can use...
#Bean
public Properties props() {
...
}
#Value("#{props.foo}")
How do you want to use SpEL in #ContextConfiguration ?

Related

is there a way to externalise the value of #Scheduled annotation in spring boot?

As #Scheduled annotation key 'fixedRate' in spring boot will only accept constant, i want to know is there any other way to externalise this property to the external properties file ?
Take a look at the documentation; Most of the properties have a String suffixed counterpart as well, in your case fixedRateString. The String-suffixed properties can be used to insert SPeL and placeholder expressions, for instance:
#Scheduled(fixedRateString="${scheduled.fixedRate}")
public void someMethod() { ... }
application.properties:
scheduled.fixedRate=1000

Reading property file in java using Spring

Have been trying to understand how to load a property file using Spring in java and populate java.util.Properties object.
Use this newly created property object as a constructor arguement for another bean.
Appreciate any pointers on this.
Thanks,
cabear
To load a properties file in Spring use the PropertiesFactoryBean to make it easier to use there is a properties tag in the util namespace you can use.
<util:properties id="props" location="location-of.properties" />
Then you have a bean named props which you can use as any regular bean.
<bean id="otherBean" class="my.app.MyClass" >
<constructor-arg ref="props" />
</bean>
When also using the property placeholder support you could use the same properties object again instead of loading it again, by referencing it using the properties-ref attribute of the property-placeholder tag.
<context:property-placeholder properties-ref="props" />
Here is how you read a properties file :
#Value("${memberaddedsubject}") // id of the content you want to read.
private String memberAddedSubject; // Taking content in String class.
To use this property file, you have to instruct spring, this way :
<util:properties id="props" location="your-location-to-props" />
Add the above line in your applicationContext.xml or the XML file you have(not web.xml)
I have put my properties file in /projectname/resources/.
I hope this is what you are looking for, if not, let me know.

Obtaining configured properties from Springs

I am trying to obtain properties' values configured in Springs context with Environment bean (like in spring PropertyPlaceholderConfigurer and context:property-placeholder checked answer).
public class SpringsPropertiesProvider implements IPropertiesProvider {
#Autowired Environment envinronment;
#Override
public String getProperty(String key) {
return envinronment.getProperty(key);
}
}
This class is registered with following xml:
<context:property-placeholder
location="classpath:myproject/example.properties" />
<context:annotation-config />
<bean class="myproject.SpringsPropertiesProvider" id="springsPropertiesProvider"/>
But SpringsPropertiesProvider.getProperty method does not return values configured within example.properties file.
What I am doing wrong and how can I get dynamic access to properties configured by placeholderconfigurer?
PS.
During environment.getPropert(key) call debugging shows that org.springframework.core.env.PropertySourcesPropertyResolver has only two entries in its propertySources field ([systemProperties,systemEnvironment]) and both entries does not contain any keys defined within example.properties.
Try this
<context:property-placeholder
location="classpath:myproject/example.properties" ignore-resource-not-found="true"/>
If the project does not startup then that means spring was not able to locate the properties file.
Speaking of which, what does your project structure look like?
Update:
The following link explains why this is not working

How to override a Spring #Autowire annotation and set a field to null?

I am a Spring neophyte who is working on a large Spring-based project that has extensive coupling between Spring beans. I am trying to write some integration tests that exercise subsets of the total application functionality. To do so, I'd like to override some of the autowiring.
For example, suppose I have a class
public class MyDataServiceImpl implements MyDataService {
#Qualifier("notNeededForMyDataServiceTest")
#Autowired
private NotNeededForMyDataServiceTest notNeededForMyDataServiceTest;
//...
}
and a context file with:
<bean id="myDataService"
class="MyDataServiceImpl">
</bean>
In my test, I have no need to use the notNeededForMyDataServiceTest field. Is there some way I can override the #Autowired annotation and set notNeededForMyDataServiceTest to null, perhaps in the XML file? I don't want to modify any of the Java classes, but I do want to avoid the (problematic) configuration of notNeededForMyDataServiceTest.
I tried doing:
<bean id="myDataService"
class="MyDataServiceImpl">
<property name="notNeededForMyDataServiceTest"><null/></property>
</bean>
That doesn't work. IntelliJ informs me "Cannot resolve property 'notNeededForMyDataServiceTest'", apparently because there are no getters and setters for that field.
I'm using Spring Framework 3.1.3.
The following configuration should work, I took the liberty of mixing in Java configuration
#Configuration
//This will load your beans from whichever xml file you are using
#ImportResource("classpath:/path/beans.xml")
public class TestConfigLoader{
// This will declare the unused bean and inject MyDataServiceImpl with null.
public #Bean(name="notNeededForMyDataServiceTest") NotNeededForMyDataServiceTest getNotNeededForMyDataServiceTest(){
return null;
}
... any other configuration beans if required.
}
And annotate your test class like so:
// In your test class applicationContext will be loaded from TestConfigLoader
#ContextConfiguration(classes = {TestConfigLoader.class})
public class MyTest {
// class body...
}
These could help:
Context configuration with annotated classes
Testing with #Configuration Classes and Profiles
Spring TestContext Framework
and profiles:
beans profile="..."
Introducing #Profile
You could create different beans definition in the XML configuration and then activate them using the -Dspring.profiles.active="profile1,profile2" env.
You're using the #Autowired mechanism wrong. The qualifier is not a property that you need to set. That's actually the name of a bean, so that the container will be able to choose one particular instance in case multiple beans of the same type are defined in the same context.
So the container will look for a bean of type NotNeededForMyDataServiceTest and the name (which would actually be the bean id in XML): notNeededForMyDataServiceTest.
What I think you want is to instruct the container to not inject anything in that field if no bean of type NotNeededForMyDataServiceTest is defined in the application context. That could be achieved simply by setting the required attribute of the annotation to false:
#Autowired(required = false)
NotNeededForMyDataServiceTest someOptionalDependency;
The only drawback of this approach would be that the container will never complain at runtime if there's nothing to inject in that field (and perhaps you would want this sanity check when your code runs in production).
If you don't want to make that dependency optional (or you can't edit that code for some reason), you'll need to provide a mock / null value for that field by setting that explicitly in your context. One option to do that would be to use Java configuration instead of XML (like in #Abe's answer) and another approach would be to make use of a factory bean which returns null (like in this question).

org.springframework.core.env.Environment.getProperty(String) returns null

I am trying to access some properties programmatically in a controller of a spring mvc application. I configured it by xml. I tried both PropertyPlaceholderConfigurer and <context:property-placeholder />
I tried to use in the controller class(saw it in a working example but it was configured with #Configuration):
#Inject
private Environment environment;
and afterwards i use:
environment.getProperty("upload.location")
but i get a null value. The entry exists in the properties file(i have only one) and also using ${...} in the xml works
A much simpler way - use #Value to inject the system property, as follows:
private #Value("${systemPropertyFoo}") String systemPropertyFoo;
In your case (I"m assuming the variable is a system property):
private #Value("${upload.location}") String uploadLocation;
This annotation depends on the PropertyPlaceholderConfigurer, so keep it in your config.

Resources