Mule ESB 3.4 Context property - spring

How can one access the properties loaded by context:place-holder in a scripting component other than having to use ${property-name}? I want to get to the object that holds these key value pairs. Something like context.getProperty("property-name").

Spring property placeholders are resolved at configuration time and not stored anywhere, so they cant be loaded afterwards.
If you need to store it you can always inject them into a bean and retrieve that from the registry.
Basically all you need to do is to declare your bean:
<spring:bean class="your.Bean" name="yourBean" >
<spring:property name="yourBeanAttribute" value="${somePlaceHolder}" />
</spring:bean>
and then you can retrieve it, and the somePlaceHolder value from the registry from within a scripting component/transformer:
<scripting:transformer doc:name="Script">
<scripting:script engine="Groovy">
<scripting:text><![CDATA[
def val = muleContext.getRegistry().lookupObject('yourBean').getYourBeanAttribute()
]]></scripting:text>
</scripting:script>
</scripting:transformer>
HTH

Related

How to find out if a property is defined in placeholder in 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!

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.

When to use <ref bean> and when to use <ref local> in Spring?

When to use <ref bean="service" /> and when to use <ref local="service" /> in Spring?
Specifying the target bean by using the bean attribute of the ref tag is the most general form, and will allow creating a reference to any bean in the same BeanFactory/ApplicationContext (whether or not in the same XML file), or parent BeanFactory/ApplicationContext. The value of the bean attribute may be the same as either the id attribute of the target bean, or one of the values in the name attribute of the target bean.
<ref bean="someBean"/>
Specifying the target bean by using the local attribute leverages the ability of the XML parser to validate XML id references within the same file. The value of the local attribute must be the same as the id attribute of the target bean. The XML parser will issue an error if no matching element is found in the same file. As such, using the local variant is the best choice (in order to know about errors are early as possible) if the target bean is in the same XML file.
<ref local="someBean"/>
This is from the Spring source reference here
The local attribute on the ref element is no longer supported in the 4.0 beans xsd since it does not provide value over a regular bean reference anymore. Simply change your existing ref local references to ref bean when upgrading to the 4.0 schema.
<ref local="someBeanId"> should be used when you have a duplicate id in your parent-child config files and you want to distinguish between the two in either config file.
<ref parent="someBeanId"> should be used in the child config file to reference the parent id.
<ref bean="someBeanId"> should be used when you do not have a duplicate id in your parent-child config files.
<ref local=".."> requires that the bean being referenced is in the same config file.
<ref bean="..."> requires only it to be in the same context, or in a parent context.
The difference is primarily one of documentation. If you see <ref local="...">, then you know you need only look in the same file to find it. Other than that, there's not much difference. I would generally use <ref bean="..."> in most cases.
In spring 4.1
the local attribute is not valid.
i used in the parent xml a name attribute for the
and in the child file a referenced the bean by the alias i gave already.

Dynamically configuring java beans based on property file in Spring

Wondering if there is a way to dynamically instantiate beans based on set of values in your property file using PropertyPlaceholderConfigurer class.
I have a java bean say Student with two attributes: "name" and "subject"
I have a property file with:
student.1.name=student1name
student.1.subject=student1subject
student.2.name=student2name
student.2.name=student2subject
Now I have a Classroom object that can take a list of students.
I am wondering if there is a way we could do this using Spring. The challenge here is that the number of students could vary.
If there was only one student object then:
<bean id="student" class="com.abc.Student">
<property name="name" value="${student.1.name}" />
<property name="subject"
value="${student.1.subject}" />
</bean>
<bean id="classRoom" class="com.abc.ClassRoom">
<property name="student" ref="student" />
</bean>
would have worked. But in this case we have a list of n Students. And the value of n could vary depending on the number of entries in the properties file.
I'm with Kevin--IMO you're going about this the wrong way.
One possible workaround would be to create a bean that takes the property file as an argument, reads it in, and exposes a list of students (which would need to be indexed on something, like the n in the existing property file).
The classroom bean could then use that list of students.
But it sure looks like you're trying to duplicate the functionality of a DB, without a DB, in an awkward way.
I don't think there's a way to do that with PropertyPlaceholderConfigurer. Usually when I have a situation like that I choose a configuration format of either JSON or XML and use GSON/Jackson/JAXB to unmarshall the data into objects.

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