I have a prototype bean 'client' for which I want to call a method 'addHandler' every time it is instantiated. I am using 'MethodInvokingFactoryBean' for this. I the docs, I can see that by default MethodInvokingFactoryBean operates in a singleton fashion and caches the result of 'getObject' to return in subsequent calls.
To circumvent this, I want to call 'setSingleton' with 'false'. I am not sure about how to do this.
<bean id="provider" class="com.example.credProvider">
<constructor-arg value="key1"/>
</bean>
<bean id="handler" class="com.example.Handler"/>
<bean id="client" class="com.example.DBClient" scope="prototype">
<constructor-arg><ref local="provider"/></constructor-arg>
<property name="endpoint" value="http://xyz:8080/" />
</bean>
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject"><ref local="client"/></property>
<property name="targetMethod"><value>addHandler</value></property>
<property name="arguments">
<ref local="handler" />
</property>
</bean>
Will adding a scope="prototype" like this help? -
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" scope="prototype">
...
</bean>
Related
Consider I have something like this in beans.xml:
<bean id="emails" class="org.some.package.SomeClass">
<property name="emailList">
<list>
<value>pechorin#hero.org</value>
<value>raskolnikov#slums.org</value>
<value>stavrogin#gov.org</value>
<value>porfiry#gov.org</value>
</list>
</property>
</bean>
But I need to add emailList property into multiple beans. How can I do that without writing property to each bean? Can externalize property and inject it into each bean?
I expect something like:
<property name="commonProp">
<list>
<value>pechorin#hero.org</value>
<value>raskolnikov#slums.org</value>
<value>stavrogin#gov.org</value>
<value>porfiry#gov.org</value>
</list>
</property>
<bean id="emailsOne" class="org.some.package.ClassOne">
<property name="emailList" ref="commonProp" />
</bean>
<bean id="emailsTwo" class="org.some.package.ClassTwo">
<property name="emailList" ref="commonProp" />
</bean>
You can do it using: util:list
<util:list id="myList" value-type="java.lang.String">
<value>foo</value>
<value>bar</value>
</util:list>
Then use this myList reference in other beans.
I have a simple bean tag in the bean xml file as shown below. This is just a dummy values
<bean id="myBeanId" class="myBeanClass">
<property name="myProperty" value=${myPassword} />
</bean>
<bean id ="myOtherBeanId" class="myOtherBeanClass">
<property name="myOtherProperty" ref="myBeanId">
</bean>
myPassword is a variable names stored in a separate properties file. Now, I instead of storing the direct value of myPassword from the properties file, I will have encrypted string in the property file and I want to call my custom written Decrypt method on myPassword property instead. something like this.
<bean id="myBeanId" class="myBeanClass">
<property name="myProperty" value=com.xxx.Security.Decrypt(${myPassword}) />
</bean>
How can I do this?
Use the MethodInvokingFactoryBean if you want to invoke another bean's method and use the returned object as a bean.
<bean id="securityBean" class="com.xxx.Security">
</bean>
<bean id="myBeanId" class="myBeanClass">
<property name="myProperty">
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject"><ref local="securityBean"/></property>
<property name="targetMethod"><value>Decrypt</value></property>
<property name="arguments">
<list>
<value>${myPassword}</value>
</list>
</property>
</bean>
</property>
</bean>
How about Using with jaspyt,
Properties file entry
password=ENC(G6N718UuyPE5bHyWKyuLQSm02auQPUtm)
Bean Entry
<bean id="myBeanId" class="myBeanClass">
<property name="myProperty" value=${password} />
</bean>
Source : http://www.jasypt.org/spring31.html
I am using Spring 3.1 and have the following spring config where I explicitly create LocalValidatorFactoryBean using my own ValidationMessageSource. I have Hibernate Validator 4.1 in my class path.
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>ValidatorMsgID</value>
</list>
</property>
</bean>
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="validationMessageSource" ref="messageSource"/>
</bean>
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/>
However I noticed that the LocalValidatorFactoryBean is being created twice by hitting a debug in classes afterPropertiesSet method. The first time is for the explicite bean that I defined in the spring config, however following that the same class is instantiated implicitly again by DefaultListableBeanFactory class - obviously this time with no validationMessageSource. Therefore it seems that when Spring does make use of the LocalValidatorFactoryBean its using the one with the default Hibernates messagesource rather than the one I have specified.
Ok, looking into this a bit further its seems that this is caused by mvc:annotation-driven I have in the spring config.
Any pointers would still help
Ok, I got it sorted eventually by adding the validator attribute to "mvc:annotation-driven". This is how my final spring config looks
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>com.mycompany.msgs.ValidatorMsgID</value>
</list>
</property>
</bean>
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="messageInterpolator">
<bean class="org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator">
<constructor-arg index="0">
<bean class="org.springframework.validation.beanvalidation.MessageSourceResourceBundleLocator">
<constructor-arg index="0" ref="messageSource"/>
</bean>
</constructor-arg>
</bean>
</property>
</bean>
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor">
<property name="validator" ref="validator"/>
</bean>
<mvc:annotation-driven validator="validator"/>
Short question: If I have class that impelemnts FactoryBean interface, how can I get from FactoryBean object itself instead of FactoryBean.getObject()?
Long question: I have to use 3-rd party Spring based library which is hardly use FactoryBean interface. Right now I always must configure 2 beans:
<!-- Case 1-->
<bean id="XYZ" class="FactoryBean1" scope="prototype">
<property name="steps">
<bean class="FactoryBean2">
<property name="itemReader" ref="aName"/>
</bean>
</property>
</bean>
<bean id="aName" class="com.package.ClassName1" scope="prototype">
<property name="objectContext">
<bean class="com.package.ABC"/>
</property>
</bean>
<!-- Case 2-->
<bean id="XYZ2" class="FactoryBean1" scope="prototype">
<property name="steps">
<bean class="FactoryBean2">
<property name="itemReader" ref="aName2"/>
</bean>
</property>
</bean>
<bean id="aName2" class="com.package.ClassName1" scope="prototype">
<property name="objectContext">
<bean class="com.package.QWE"/>
</property>
</bean>
Actyually defintion of a bean with name "XYZ" (compare with "XYZ2") never will be changed, but because of factory nature I must copy the code for each configuration.
Definition of a bean with name "aName" always will be new (i.e. each configuration will have own objectContext value).
I would like to simplify the configuration have a single factory bean (remove "XYZ2" and rid of link to "aName"):
<bean id="XYZ" class="FactoryBean1" scope="prototype">
<property name="steps">
<bean class="FactoryBean2"/>
</property>
</bean>
<bean id="aName" class="com.package.ClassName1" scope="prototype">
<property name="objectContext">
<bean class="com.package.ABC"/>
</property>
</bean>
<bean id="aName2" class="com.package.ClassName1" scope="prototype">
<property name="objectContext">
<bean class="com.package.QWE"/>
</property>
</bean>
Unfortunately, it's not as simple as I expect. I suppose to glue factory (i.e. XYZ bean from the example) with necessary objects (i.e. "aName", "aName2") at runtime.
The approach doesn't work because when I ask Spring for FactoryBean object it returns to me FactoryBean.getObject() which impossible to instanciate at that time because of missing itemReader value.
I hope that SpringSource foresee my case I can somehome "hook" FactoryBean.getObject() call to provide all necessary properties at runtime.
Another complexity that disturb me a bit it's chains of Factories (Factory1 get an object from Factory2 that I have to "hook" at runtime).
Any ideas will be appreciated.
It's the & (ampersand), not the At-symbol, see Spring Framework documentation: Customizing instantiation logic using FactoryBeans
<property name="factoryBean" ref="&theFactoryBean" />
You can get the factory bean itself using the & syntax in the spring config:
<property name="factoryBean" ref="&theFactoryBean" />
as opposed to:
<property name="createdBean" ref="theFactoryBean" />
I've declared the following bean in my Spring config
<bean id="templateCacheClearingTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="delay" value="5000" />
<property name="period" value="5000" />
<property name="timerTask">
<bean class="org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean">
<property name="targetObject" ref="templateMailService" />
<property name="targetMethod" value="clearCache" />
</bean>
</property>
</bean>
This should cause the clearCache() method of the templateMailService bean to be invoked every 5000ms, but nothing appears to be happening. Am I missing something?
Cheers,
Don
I think you need:
<bean id="timerFactory" class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks">
<list>
<ref bean="templateCacheClearingTask"/>
</list>
</property>
</bean>
In addition to what you already have.