For example I am having two properties file like message and query. how can configure in the spring xml
Well, you could use the below code snippet.
<context:property-placeholder
location="classpath:dao.properties,
classpath:services.properties,
classpath:user.properties"
ignore-unresolvable="true"/>
In this, the order attribute needs to be specified to fix the order in which these are processed by Spring.
All property placeholders minus the last one (highest order) should have ignore-unresolvable="true" to allow the resolution mechanism to pass to others in the context without throwing an exception
Related
I find Spring Boot's (or spring in general) handling of yaml collections to be a bit peculiar. Collections according to yaml specs should be written in .yaml files as:
myCollection: ['foo', 'bar']
or
myCollection:
- foo
- bar
But neither #Value("${myCollection}") annotation or Environment.getProperty("myCollection", String[].class) (also tried List.class) can read collection properties (returns null). The only method I know of that works is to use #ConfigurationProperties annotation described in spring boot docs.
The problem with #ConfigurationProperties annotation is that (a) it is too verbose if all I want is a single property and (b) it rely on bean injection to get an instance of the #ConfigurationProperties class. Under some circumstances, bean injection is not available and all we have is a reference to Environment (e.g: thru ApplicationContext).
In my particular case, I want to read some properties during ApplicationEnvironmentPreparedEvent event, since it happens before context is built, the listener has to be manually registered and therefore, no bean injection. Via the event argument, I can get a reference to Environment. So, I can read other properties but cannot read collections.
A couple of "solutions" I noted (quoted because I don't find them very satisfactory):
Specify collections in .yaml file as myCollection: foo, bar. But this is not ideal because, the format isn't really yaml anymore.
Read individual elements using an index, for example Environment.getProperty("myCollection[0]", String.class). Will require some not-so-elegant utility methods to read and put all elements into a List.
So, my questions is - What is a good way to read collection-type properties if I cannot use #ConfigurationProperties? Also curious why comma-separated format works but not yaml-style collections.
EDIT: corrected some typos
Quite Frankly Spring boot application.properties and application.yaml or application.yml is meant to load configuration properties.
The #ConfigurationProperties annotation is designed as an abstraction to hide the implementations of configuration properties and support both .properties and .yaml/.yml.
For yaml/yml however Spring uses org.yaml.snakeyaml.Yaml library underneath to parse the file and load it to a Properties object inside org.springframework.boot.env.YamlPropertySourceLoader and a Collection is mapped as a Set not an array or List. So you try doing the following;
Environment.getProperty("myCollection", Set.class)
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.
I have a spring bean defined like
<util:set id="siteLanguages" value-type="java.util.Locale" set-class="java.util.LinkedHashSet">
<value>#{T(java.util.Locale).GERMAN}</value>
<value>#{T(java.util.Locale).ITALIAN}</value>
<value>#{T(java.util.Locale).ENGLISH}</value>
</util:set>
I'm wondering how can I pass the value list definitions to the bean as a properties list value.
<util:set id="siteLanguages" value-type="java.util.Locale" set-class="java.util.LinkedHashSet">
???
</util:set>
I would like to have in my properties file something like
site.languages=#{T(java.util.Locale).GERMAN},#{T(java.util.Locale).ITALIAN},#{T(java.util.Locale).ENGLISH}
or even better
site.languages=GERMAN,ITALIAN,ENGLISH
and pass this in to the bean
The main problem is that you cannot express multivalue data structures (arrays, lists etc) in plain java property files by using the java standard api.
You can do it easily though with Apache commons configuration library.
http://commons.apache.org/proper/commons-configuration/
Can I use a property loaded from property-placeholder to make a context import dynamic?
<context:property-placeholder location="classpath*:/enterprise.properties"/>
<import resource="classpath*:/Fsb${jdbc.ctxType?:Jdbc}-context.xml"/>
Properties File
jdbc.ctxType=JTA
So this way I could change the type of context file that is loaded based on a property.
Also, can I do the same thing to make a bean ref name dynamic?
<bean id="personBusinessService" class="com.foo.PersonBusinessServiceImpl"
p:personUidDataService-ref="personUidDataService${personUidDataService.sib?:Api}"
p:identifierLookupSearchService-ref="identifierLookupSearchService${identifierLookupSearchService.sib?:Api}"
p:contactPointBusinessService-ref="contactPointBusinessService${contactPointBusinessService.sib?:Api}"
/>
Properties File
personUidDataService.sib=Stub
Jay
--------------------Update example of property for ref-------------------------
I created a property file with the following entry:
addressLookupSearchService.sib=DaoMock
Then I have the following configuration in a Spring Context File:
<context:property-placeholder location="classpath*:/simple.properties"/>
<!-- EntityManager will be injected into DAO by JPA annotations -->
<bean id="addressSearchDao" class="com.foo.AddressSearchDaoImpl"/>
<bean id="addressSearchDaoMock" class="com.foo.MockAddressSearchDaoImpl"/>
<bean id="addressLookupSearchService" class="com.foo.AddressLookupSearchServiceImpl"
p:baseDao-ref="addressSearch${addressLookupSearchService.sib?:Dao}"/>
And addressSearch${addressLookupSearchService.sib?:Dao} doesn't work, it always defaults to
the bean id of addressSearchDao even if my property says it should set to addressSearchDaoMock.
Any thoughts as to what I am doing wrong?
This is a similar question to this one.
Imports are resolved before bean (property-placeholder) creation, so you can not use the property file to define properties which you want to use in an import statement. In this case you have to set the property as system property (-Djdbc.ctxType=JTA) (have a look at the link - paragraph Note).
But using the property file properties in bean definitions works fine - that's what they are for :-)
Update: Since Spring 3.1 the Unified Property Management allows to use properties even in imports (thanks #Jay Blanton for mentioning this in the comments).
Yes, you can. You can use expressions in imports and injections.
As far SpEL is used in Spring 3.0,
I would like to ask, is it possible to do following(in bean definition .xml):
<c:choose>
<c:when test="#{prop=='a'}">
<bean class="BeanA"/>
</c:when>
<c:otherwise>
<bean class="BeanB"/>
</c:otherwise>
</c:choose>
Someth. like in jstl.
Thank you for help.
Environment profiles/Environment specific beans will be available in Spring 3.1 which should be released shortly - so you might want to wait for that.
There is no built in support for conditional beans in Spring 3.0. However, it could be achieved by using PropertyPlaceholderConfigurers and/or FactoryBeans.
There's no conditional mechanism for XML Spring bean defintion files.
However, maybe this would work:
<bean class="#{prop=='a' ? BeanA : BeanB}"/>
But even if this approach worked, it wouldn't be the most readable one. My suggestion would be to use different set of XML configuration files and pick them depending on some global settings. Naturally you would put all the common beans (i.e. these whose definition is always the same) in a separate file and have it always included.
it is not a question of using spel, but more of XML,afaik you can't do this in XML (but xslt)
the proper spring way for this scenario might be http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-factory-class in combination with a "parent" interface for BeanA and BeanB
you could pass the parameter (system ? runtime specific ?) to the factory, which would create either BeanA or BeanB