How to set constructor based injection values - spring

<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

Related

Dependency Injection returned results of bean init-method

I have two simple beans. In the first bean it calls a init-method and return string value.
Now I want to this returned string from first bean init-method , inject to my second bean
helloWorldBean3 property newKey. Please advise me on how to implement this requirement.
<bean id="helloWorldBean2" init-method="loadKey"
class="com.java.snippets.enterprise.services.HelloWorld2">
<property name="key" value="${key.supportiveFile}" />
<bean id="helloWorldBean3"
class="com.java.snippets.enterprise.services.HelloWorld">
<property name="newKey" ref="???" />
</bean>
Try using Spring EL like so:
<bean id="helloWorldBean3"
class="com.java.snippets.enterprise.services.HelloWorld">
<property name="newKey" value=""#{helloWorldBean2.loadKey()}"" />
</bean>

How would I specify a bean reference as an argument-resolver, in Spring 3-1?

This is a syntax question about a Spring configuration (refer to spring-beans-3.1.xsd and spring-mvc-3.1.xsd).
I have a specific bean definition (id="SecurityRequestParametersArgumentResolver") that I want to register as a custom argument resolver. The xml fragment is:
<bean id="SecurityRequestParametersArgumentResolver"
class="xxx.security.web.SecurityRequestParametersArgumentResolver">
<property name="credentialsManager" ref="CredentialsManager" />
<property name="tokenService" ref="TokenService" />
</bean>
... AND I would like to use a bean reference. The following three lines don't obey the xsd-grammar ( what should be the correct tag declaration here? )
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean ref="SecurityRequestParametersArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
... All of the examples I have seen look like THIS, and thus are going after the default no-argument constructor
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="class="xxx.security.web.SecurityRequestParametersArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
Repeating the question, what should the Spring syntax be in order to use a bean reference as a custom argument resolver?
Thanks!
At least the constructor argument problem can be solved easily
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="class="xxx.security.web.SecurityRequestParametersArgumentResolver">
<constructor-arg value="123"/>
</bean>
</mvc:argument-resolvers>
</mvc:annotation-driven>
But I do not know any way to use a reference instead of a bean within <mvc:argument-resolvers>. But depending on what you want to do, there are several workarrounds.
Use a Bean Factory
Create a proxy class that implements the HandlerMethodArgumentResolver and forward every call to an other instance, then you can have your own SecurityRequestParametersArgumentResolver like a normal bean and register the Proxy in the <mvc:argument-resolvers> section.
Proxy:
class HandlerMethodArgumentResolverProxy
implements HandlerMethodArgumentResolver{
HandlerMethodArgumentResolver delegate;
publicHandlerMethodArgumentResolverProxy
(HandlerMethodArgumentResolver delegate){
this.delegate=delegate;
}
public boolean supportsParameter(MethodParameter parameter) {
this.delegate.supportsParameter(parameter);
}
//delegate for resolveArgument
}
config:
<bean id="securityRequestParametersArgumentResolver"
class="xxx.security.web.SecurityRequestParametersArgumentResolver">
...
</bean>
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class "HandlerMethodArgumentResolverProxy">
<constructor-arg
ref="securityRequestParametersArgumentResolver"/>
</bean>
</mvc:argument-resolvers>
</mvc:annotation-driven>

How to add a param to a factory-method of a factory-bean in Spring?

let's say I have a factory bean:
<bean id="myFactory" class="com.company.MyFactory" lazy-init="true">
<property name="myProperty" ref="propA">
</bean>
Let's say propA is a bean injected by IOC used in the factory method. And I have 2 beans generated from this factory:
<bean id="bean1" factory-bean="myFactory" factory-method="instance"/>
<bean id="bean2" factory-bean="myFactory" factory-method="instance"/>
How can I make bean2 to use a different myProperty than bean1 without using a different factory method? Or, how can I pass propA as a parameter to the factory-method from the bean1 or bean2 configuration?
This can be achieved in a slightly different way:
class MyFactory {
public Bean instance(MyProperty myProperty) {
return //...
}
}
Now you can use counterintuitive syntax like following:
<bean id="bean1" factory-bean="myFactory" factory-method="instance">
<constructor-arg ref="propA"/>
</bean>
<bean id="bean2" factory-bean="myFactory" factory-method="instance">
<constructor-arg ref="propB"/>
</bean>
Believe it or not but propA and propB will be used as instance() method arguments.

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