How to pass JobParams to other beans in xml? - spring

There are two job params filePath & fileName for my spring batch job. Requirement is to pass this filePath+fileName to other custom bean as a property value. However, I cannot "step" scope that bean to access these params. Hence I need a way to access these job params from (non-step) normal bean. Pls refere below code ::
<bean id="cardDownloadFileTemplate"
class="org.springframework.integration.file.remote.RemoteFileTemplate">
<constructor-arg ref="sftpSessionFactory" />
<property name="fileNameExpression">
<bean class="org.springframework.expression.common.LiteralExpression">
<constructor-arg
value="#{jobParameters['filePath']}#{jobParameters['fileName']}}" />
</bean>
</property>
<property name="charset" value="${fserver.charset}" />
</bean>

It can't be done; for normally-scoped beans (singleton, prototype) the bean is initialized with the context, before the job is launched; there is no jobParameters variable available.

You can setup the normal beans as Step Listeners, and then implement the #BeforeStep method which can extract the JobParameters from the step execution.
In this case the value for the parameter you are extracting will not be available at bean initialization but will be able just before the step starts to run.
Initialize the state of the listener with the StepExecution from the current scope
beforeStep(StepExecution stepExecution)
stepExecution --> getJobParameters()

Related

How to set constructor based injection values

<bean id="someBean" class="someClass" >
<constructor-arg index="0" value=""/>
<constructor-arg index="1" value=""/>
</bean>
</beans>
How can I set values from java code?
You can pass the constructor arguments to getBean method as below. But this will work only if the scope of your bean is configured as prototype.
context.getBean("someBean" , new Object[] {"kswaughs", "Stackoverflow user"} );
If you try to call this method for singleton beans, Spring will throw below error.
org.springframework.beans.factory.BeanDefinitionStoreException: Can only specify arguments for the getBean method when referring to a prototype bean definition

How can i use a specific proprety for each bean call in Spring

I'm developing an application using spring . I have a bean that i need to call multiple times but for each call i need to change the properties values dynamically . Is there a way to do this .
I had an idea to set the bean properties as an array ,in eatch array i put the parameters that i want to use . For example array[0] contains the params of the first call , array[1] params of the second call,... is it possible to do that ?
Here is a code sample :
<bean class="Dummy2">
<!-- or a list of values -->
<property name="foos">
<util:list>
<value>A,b,c</value>
<value>X,y,z</value>
<value>1,2,3</value>
<value>7,8,9</value>
</util:list>
</property>
</bean>
the setter
#Override
public void setFoo(list<String[]> args) {
...
}
If any one have a better idea or a usefull idea i will be grateful
Thank You
This is the propreties of the bean that calls the beans
<property name="activities">
<list>
<ref bean="1"/> //Calling bean 1
<ref bean="2"/> //Calling bean 2
<ref bean="1"/> //Calling bean 1 again
<ref bean="2"/>//Calling bean 2 again
<ref bean="2"/>
</list>
</property>
i need to use different parameters for each call (call the setter with different values)
Would using Spring's PostConstruct annotation on an initialiser method on your 'master' bean be useful? You could use simple setter methods to inject both the list of beans and the list of configurations into the master bean, and in the init method (annotated with #PostConstruct) configure each bean correctly.
http://static.springsource.org/spring/docs/3.2.x/spring-framework-reference/html/beans.html#beans-postconstruct-and-predestroy-annotations
Are you familiar with AOP you can use aspect to do this using #Before Advice to set your method properties before calling it

Spring 3.0 RmiProxyFactoryBean: how to change serviceUrl at runtime?

I have a bean definition like this:
<bean id="myService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceInterface" value="org.myapp.MyService"/>
<property name="serviceUrl" value="rmi://localhost:1099/myService"/>
</bean>
I retrieve the service bean in this way:
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:rmi-client-config.xml");
MyService myService = context.getBean("myService", MyService.class);
Of course it returns an Instance of "MyService" impl and not RmiProxyFactoryBean.
So how can I change "serviceUrl" parameter using the xml definition above and not manually instancing RmiProxyFactoryBean?
To get the FactoryBean instance instead of the bean created by the factory, use the BeanFactory.FACTORY_BEAN_PREFIX. ie
RmiProxyFactoryBean rpfb = (RmiProxyFactoryBean) contex.getBean("&myService");

Creating a Spring Bean using FactoryMethod with variable arguments from Spring?

How can we create a bean using FactoryMethod with variable arguments.
public class ConnectionFactoryClass {
public static Connection composeConnection(final Property... properties) {
...
}
}
bean.xml
<bean id="Connection"
class="com.example.ConnectionFactoryClass"
factory-method="composeConnection"
scope="singleton">
<constructor-arg ref="Driver"/>
<constructor-arg ref="Pool"/>
</bean>
Spring is giving me an error saying,
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'Connection' defined in file [./beans.xml]: No matching factory method found: factory method 'composeConnection'
Try the following:
<bean id="Connection"
class="com.example.ConnectionFactoryClass"
factory-method="composeConnection"
scope="singleton">
<constructor-arg>
<array>
<bean ref="Driver" />
<bean ref="Pool" />
</array>
</constructor-arg>
</bean>
I think you are having a problem because the JVM turns a var arg params into an Object Array and you need to pass in a single paramater to the constructor which is the array of objects. I have not tried the above xml so I might have typos in it, but something like the above should work.

constructor injection with value provided by another bean

I want to pass value to constructor(type string) with value provided by another bean.
Class BeanOne () {
BeanOne (String message) {
...
}
}
Below declaration will work
<bean id="beanOne"
class="com.abc.BeanOne">
<constructor-arg index="0" type="java.lang.String"
value="Hi There" /> // instead of value="Hi There", i want to use bean property (value="someBean.message")
</bean>
However I want another bean (say BeanTwo) to set value for message property for BeanOne. I tried nested property as given below but it does not work. Also message property is not visible directly in the class & is referred internally by another constructor & then by the method so i cannot use property injection& have to use only constructor injection
You can use the MethodInvokingFactoryBean to get your string value and then inject that into your bean.
<bean id="message" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject"><ref local="someBean"></property>
<property name="targetMethod"><value>getMessage</value></property>
</bean>
<bean id="beanOne" class="com.abc.BeanOne">
<constructor-arg index="0" type="java.lang.String" ref="message"/>
</bean>

Resources