How can i use a specific proprety for each bean call in Spring - 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

Related

How to initialize a bean basis on propertiy file boolean key value pair

I am new to spring, Is there any way to initialize spring bean using property file key-value pair;
; if like my config.properties file contains isSetup = true;
then only initialize, <bean id="a" class="com.Setup"/>
Please refer this post
How can I inject a property value into a Spring Bean which was configured using annotations?
This link can also help you : http://springinpractice.com/2008/12/02/new-stuff-in-spring-30/
You can pass the property as below to bean :
<bean id="a" class="com.Setup"/>
<property name="isSetup " value="#{systemProperties.isSetup }"/>
</bean>

Convert XML bean definition with parent to Java with annotations

I have an application using a framework that provides certain Spring beans via XML files in the framework. The configuration of my application is currently done partly in XML but mostly with Spring annotations.
Some of the XML bean definitions have parents referring to beans supplied by the framework, e.g.
<bean id="MyBean" parent="FrameworkBean">
<property name="context">
<map merge="true">
<entry key="SomeKey" value-ref="SomeValue" />
</map>
</property>
</bean>
FramwworkBean is defined in an XML file in the framework. There is a chain of bean inheritance. At each step some entries are added to the context:
<bean id="FrameworkBean" parent="AbstractBean">
<map merge="true">...
<bean id="AbstractBean" abstract="true" class="ClassWithContext"/>
I understand the result of all this is construction of a ClassWithContext
instance with a map containing all the entries up the chain.
Is it possible to write Java code to do the same, without duplicating code from the framework XML files?
#Bean("MyBean") ClassWithContext myBean() {
return ??? // code that uses "FrameworkBean" somehow
}
The XML bean definition has no dependency on the type of AbstractBean.
If MyBean can be created by Java code, can that code be written to be equally type-agnostic? Or should I just leave this in XML?
If your "FrameworkBean" is not abstract bean you can try the following:
#Bean
public SomeType myBean(#Qualifier("FrameworkBean") FrameworkBeanType frameworkBean) {
SomeType type = getSomeType();
type.setFrameworkBean(frameworkBean);
return type;
}

How to pass JobParams to other beans in xml?

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()

How do I inject a Class[] array in spring?

I've got a class which has a static method newInstance(Class[] classes, List properties), and I need Spring to be able to instantiate instances using this class.
What i've got so far in my XML configuration is :
<bean id="jaxbContext" scope="prototype" class="javax.xml.bind.JAXBContext" factory-method="newInstance">
<constructor-arg>
<list>
<value type=">com.company.pas.entity.Partner.class</value>
</list>
</constructor-arg>
<constructor-arg>
<list>
<value>com/company/pas/entity/mapping/partner-pojo2xml.xml</value>
</list>
</constructor-arg>
</bean>
This throws the below exception. Note that it complains that it can't find the newInstance method, but i assume that is because it can't find a newInstance method with a signature which matches the configuration. I suspect that Spring interprets the list of classes as java.lang.String, and not Class.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jaxbContext' defined in class path resource [com/company/pas/context/mappingContext.xml]: No matching factory method found: factory method 'newInstance'. Check that a method of the specified name exists and that it is static.
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:500)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:964)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:870)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:479)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:450)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:309)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:189)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322)
... 46 more
How do I get spring to inject an array of Class[] based on a configuration file?
JAXBContext.newInstance() has this overload:
newInstance(String contextPath)
newInstance(String contextPath,ClassLoader classLoader)
newInstance(Class... classesToBeBound)
newInstance(Class[] classesToBeBound,Map<String,?> properties)
newInstance(String contextPath,ClassLoader classLoader,Map<String,?> properties)
To be honest I can't find a newInstance(Class[] classes, List properties) overload so spring is right when tells you it can't find the newInstance() method

Getting an instance of a bean excplicitly in runtime

I have a case where I have a bean (let's call it A) which needs some other bean (B).
This B is retrieved from a static method of a class using MethodInvokingFactoryBean.
This static method depends on the state of the system and will work after the web application is loaded.
I need to access the B only in runtime (no interaction in the constructor).
How can I configure the A to autowire bean B and only initialize it the first time A requires it?
Is using getBean on the Application context the only way?
Thanks!
*Edit - Added some xmls :) *
This is the definition of bean B.
<bean id="api" class="com.foo.API"/>
<bean id="B" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" lazy-init="true">
<property name="targetObject" ref="api"/>
<property name="targetMethod" value="getFactory"/>
<qualifier value="myQualifer"/>
</bean>
This is the definition of bean A.
<bean id="resources.someRESTResourceA" class="com.foo.MyRestResource"/>
I can't use Autowire to wire B into A because it will initialize it (B) on A's construction.
B's targetMethod will only work after the web app has been initialized.
I can use ApplicationContext.getBean("B") inside A, but it's not elegant and will be a problem with unit testing unless I do the following (which is also not desired):
public BInterface getB() {
if (b == null) {
b = ApplicationContext.getBean("B");
}
return b;
}
you should lazily initialize bean A.
<bean id="A" class="demo.A" lazy-init="true">
<property name="b" ref="B"/>
</bean>
You still need to retrieve the bean A from the Spring container when you need it with the getBean() method. It's easily accesible with the ApplicationContextAware interface.
If you autowire bean A into an another bean and that bean is retrieved before bean B is constructed, the Spring container will create bean A at the time it's injected as a property to the another bean.

Resources