Is it possible use HashMultimap to create spring bean? - java

XML:
<bean id="myBean" class="com.google.common.collect.HashMultimap">
<constructor-arg index="0" value="200"/>
<constructor-arg index="1" value="2"/>
</bean>
Is it correct? When I try to inject this bean in another like:
<property name="myBean" ref="myBean"/>
i received the error: Cannot apply property values to null instance

try this
<bean id="myBean" factory-method="create" class="com.google.common.collect.HashMultimap">
<constructor-arg index="0" value="200" />
<constructor-arg index="1" value="2" />
</bean>

HashMultimap does not have a public constructor, therefore it's neither a Bean nor a POJO.
Source: google collections - HashMultimap
Instances are created using the static factory methods, among them one with no arguments (create()), maybe you can use this?

Related

Java Spring IOC bean creation value

I need a bean like this
<bean id="studentWithSchool" class="com.model.Student" scope="prototype">
<property name="school">
<bean class="com.model.School" scope="prototype"/>
</property>
</bean>
This is OK.
My problem is I have the student returning from a method from a different bean.
I usually load the bean like this when is a property.
<property name='beanProperty' value='#{anotherBean.getBeanProperty()}'/>
But in this case I need the new bean itself being set from the other bean method (School object is returned from another bean method).
This is what I try, and of course this is wrong:
<bean id="studentWithSchool" class="com.model.Student" scope="prototype" value='#{anotherBean.getBeanProperty()}'>
<property name="school">
<bean class="com.model.School" scope="prototype"/>
</property>
</bean>
Is there any workaround?
If I understand you correctly, the studentWithSchool is created and returned by a method in anotherBean. If that's the case, you can use a factory-method:
<bean id="studentWithSchool" factory-bean="anotherBean" factory-method="getBeanProperty" scope="prototype" />
I believe you are trying to use factory patter with Spring . For that you can use factory bean from spring.
<bean id="studentWithSchool" factory-bean="anotherBeanStaticFactory" factory- method="createBeanProperty" scope="prototype"
<property name="school">
<bean class="com.model.School" scope="prototype"/>
</property>
For more detail you can use below link :-
http://docs.spring.io/spring-framework/docs/2.5.6/api/org/springframework/beans/factory/BeanFactory.html

Instantiate a priority queue with a comparator from spring

As part of learning spring, I'm trying to declare a priority queue bean of MyMessageObject objects, but keep getting the following BeanCreationException: "Error creating bean with name 'messagesHeap' defined in URL [file:/my.app.spring.xml]: Could not resolve matching constructor"
Here's my spring definitions:
<bean id="messagesHeap" class="java.util.PriorityQueue">
<constructor-arg type="int" name="initialCapacity" value="100" index="0"/>
<constructor-arg name="comparator" type="java.util.Comparator" index="1" ref="orderComparator"/>
</bean>
<bean id="orderComparator" class="com.my.myComparator"/>
The class myComparator implements java.util.Comparator as required.
What am I doing wrong here?
try this
<bean id="messagesHeap" class="java.util.PriorityQueue">
<constructor-arg value="100" />
<constructor-arg ref="orderComparator" />
</bean>

Populate Spring Bean with the return value of a function

I want to populate a value of my spring bean with the return value of a method. Is there any way I can do this?
<bean id="JmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="defaultDestinationName"
value="#Value#returned#by#method" />
I already have a bean of the class which has the method in my application context.
<bean id=xyz class=path.to.xyz>
</bean>
Please note that the value that I want to inject is not a variable, but return value of a method.
You can use factory-bean and factory-method:
<bean id="JmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="defaultDestinationName">
<bean factory-bean="xyz" factory-method="methodName" />
</property>
</bean>
If the method you want to call takes parameters you can pass them in using constructor-arg
<bean factory-bean="xyz" factory-method="methodName">
<constructor-arg index="0" value="firstParameter" />
<constructor-arg index="1" ref="someOtherBean" />
</bean>
This can be achieved with Spring expression language
<bean id="b1" class="B1">
</bean>
<bean id="b2" class="B2">
<property name=xxx" value="#{b1.xxx}" />
</bean>
you can just do
<bean id="JmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="defaultDestinationName"
value="#{className.methodName()}" />
The spring container will call the geter method for that property
Note: you woudl have to autowire path.to.xyzConfig using #autowire
References 1 : Look for this : 6.4 Expression support for defining bean definitions
This question could help
In short, you could use a factory method to return the value you want.

Autowiring beans

I've created a few beans for validation of an object:
<!-- RES rules engine -->
<bean id="rules-execution-server-engine"
class="util.res.RuleEngineRESJSE">
<constructor-arg index="0" value="util.res.rulesengine.log" />
</bean>
<bean id="rio-object" class="UROImpl">
</bean>
<bean id="trade-validator-context"
class="rule.trade.TradeValidationContext">
<constructor-arg index="0" ref="rio-object" />
</bean>
<bean id="trade-validator"
class="validator.RESTradeValidator">
<constructor-arg index="0" ref="trade-validator-context" />
<constructor-arg index="1" ref="validation-rules-helper" />
</bean>
<bean id="validation-rules-helper"
class="util.res.RESRulesHelperImpl">
<constructor-arg index="0" value="rule.traderules.loc" />
<constructor-arg index="1" ref="rules-execution-server-engine" />
</bean>
I can call and create them through a main method sucessfully.
However I am now trying to integrate this code within my other modules.
The trade-validator bean implements a interface which looks like:
public interface IValidator {
public Object validate(Object obj) throws ValidationException;
}
I am hoping to call this via the interface:
validator.validate(rioObject);
However this is causing issues as I cannot instanate the interface and from the XML you can see the actual requires two other beans for it's constructor. I've been looking at the autowired approach. But am still getting to grips with it.
Is there a way to point it towards the bean as being the validator to use? As atm the validator is null.
My recommendation is to avoid using autowire for bigger deployments and wire the beans yourselves.
BTW, why are you not able to instantiate the trade validator ? What is the error that you are getting?
However this is causing issues as I cannot instanate the interface and
from the XML

spring: set property of one bean by reading the property of another bean?

Is it possible to set the property of one bean by reading the property of another bean? For instance, suppose I had:
class A {
void setList(List list);
}
class B {
List getList();
}
I would like Spring to instantiate both classes, and call A's setList method, passing in the result of calling B's getList method. The Spring configuration might look something like:
<bean id="b" class="B"/>
<bean id"a" class="A">
<property name="list" ref="b" ref-property="list"/>
</bean>
Alas, this made-up XML does not work.
Why not just inject B into A? Because I do not want to introduce the extra dependency. A is only dependent List, not on B.
in addition to #Kevin's answer if you are using spring 3.0 it is possible to do this with the new spring expression language
<bean id="a" class="A">
<property name="list"
value="#{b.list}"/>
</bean>
spring 3.0 documentation
There are a couple of ways. Here is one:
<bean id="b" class="B"/>
<bean id="a" class="A">
<property name="list">
<bean class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
<property name="targetObject" ref="b"/>
<property name="propertyPath" value="list"/>
</bean>
</property>
</bean>
Also see the <util:property-path/> element
If you are trying to do the same for a constructor then do this.
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg type="javax.sql.DataSource" value="#{jdbc.dataSource}">
</constructor-arg>
</bean>
Here "jdbc" is as mentioned below that has property "dataSource" with getter and setter and initilized as:
<bean id="jdbc" class="com.la.activator.DataSourceProvider">
<property name="myDataSourcePool" ref="dsPoolService"/>
</bean>

Categories