How to find out if a property is defined in placeholder in Spring? - spring

Due to some backward compatible reasons, some old apps didn't define a new property in its app.properties, which is referred in a shared Spring context.xml thru placeholders. Is there a way in Spring to find out if a property is defined in the placeholder?
There are posts about setting null default values using Spring expression language. But, I don't see an answer on how to determine if a property is defined in the placeholder, or you'd get "Could not resolve placeholder ...".
I'm looking for something like
<constructor-arg value="#{someAPI('my.new.prop') ? ${my.new.prop} : #null}" />
Your input is highly appreciated!

Related

How does Spring Data JPA resolve property name containing single letter abbreviation for a word in query methods?

I've an entity with property name qYear. I tried creating a findByIdAndQYear method in repository but that did not work. I ran into IllegalArgumentException: Unable to locate Attribute with the the given name [QYear] on this ManagedType).
However findByIdAndqYear works. Any idea how single letter abbreviations like this are expanded please?
Spring Data (not just the JPA module) base this on the Java Bean Specification.
In order to avoid misinterpretation of the specification this is actually implemented using [java.beans.Introspector][1].
See also https://jira.spring.io/browse/DATACMNS-1589

Spring property value - res: URI

I've been using spring for years but can't seem to find documentation on this one. If I have a spring bean configured like this:
<bean id="myBeanInstance" class="org.mybean">
<property name="path" value="res:a-string-goes-here"/>
</bean>
Is the value being interpreted as purely a string? How does 'res:' affect anything and where is it being interpreted? Any pointers to the appropriate docs would be fantastic.
Thanks!
Yes, the value is interpreted purely as string...
Unless you have a BeanFactoryPostProcessor, such as weirdly configured PropertyPlaceholderConfigurer or some custom BeanFactoryPostProcessor to take care of such values.
Note also, that since Spring 3 the ':' is the default separator for default property values, i.e. if you have PropertyPlaceholderConfigurer with default setting, the value "${res:whatever}" would be treated as a property 'res' with default value 'whatever'.

How to get property from context property placeholder tag inside custom java component

I have Mule Configuration that defines
<context:property-placeholder location="classpath:/mule-sw.properties"/>
And I also have a custom component class in Java which use #Lookup annotation on one of my field
#Lookup("file-path")
private String path;
Considering my "mule-sw.properties" is like this
file-path=C:/hello.txt
After I start up the Mule App, I always get Deploy Exception
org.mule.api.expression.RequiredValueException: "Required object not found in registry of Type "class java.lang.String" with name "file-path" on object "class component.CustomComponent"
I also tried to change the #Lookup("file-path") with #Lookup("${file-path}") with no success.
Anyone can give me a better solution ?
Any help is kindly appreciated.
Thanks
The #Lookup annotation is designed to retrieve objects from the registry , whereas what you are trying to do is to assign a value to an attribute of your custom component.
There are 2 way to do that:
1) Through property injection, i.e. you declare your component like the following:
<custom-component class="org.myCompany.CustomComponent">
<property name="file-path" value="${file-path}" />
</custom-component>
2) Through Spring EL support and the #Value annotation, i.e. you annotate your attribute in the following way
#Value("${file-path}")
private String path;
I'd recommend the first approach since it is easier to maintain from a flow perspective
#Value("#{'${file-path}'}")
private String path;
Give this a shot. I think you need to wrap it in an EL block #{} for it to be properly recognized.

Spring Framework (V2.5) - Using actionpath in ref attribute in a bean definition

I am a pretty newcomer for Spring Framework.
This is regarding referencing another bean using ref attribute.
I have a bean definition for an action class like below.
<bean name="/abc" class="com.example.actions.Action" scope="singleton">
<property name="businessLogic" ref="/pqr"/>
</bean>
I am trying to inject another bean into this bean using ref attribute (ie "/pqr").
<bean name="/pqr" class="com.example.businesslogic.PqrBL" scope="prototype" />
Now my question how normal is it to use name="/pqr" kind of a notation for a bean which is not a definition for some action class ? By convention is it an acceptable normal scenario ?
PS: please let me know if information provided is incomplete or the question is not clear.
Thanks
The Spring reference states that
The convention is to use the standard Java convention for instance field names when
naming beans. That is, bean names start with a lowercase letter, and are camel-cased from
then on. Examples of such names would be (without quotes) 'accountManager',
'accountService', 'userDao', 'loginController', and so forth.
It is not normal to use "/pqr" as a bean name but you can do it . I would prefer using more user friendly names to the beans than using a "path" .
Check here for the convention .

Property Placeholder for Imports/Bean Refs

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.

Resources