Instantiate a priority queue with a comparator from spring - java

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>

Related

Spring Bean initialization - Date passed as String via xml not working for step scope

I need to pass currentDate as String to my sendMetaStatsTask tasklet appended in subject .
Now, if I create a bean with scope="step" using following xml
<bean id="sendMetaStatsTask" class="org.springframework.batch.core.step.tasklet.MethodInvokingTaskletAdapter" scope="step">
<property name="targetObject">
<bean class="com.nextag.catalog.springbatch.tasklets.GenerateReportFromQueriesTasklet">
<property name="mailTo" value="#{jobParameters['MAIL_TO']}"/>
<property name="mailFrom" value="#{jobParameters['MAIL_FROM']?:'wizereporter#nextag.com'}"/>
<property name="mailSubject" value="#{jobParameters['PARTNER_DOMAIN']+' Affiliate Seller Report - '+ currentDate.toString()}"/>
</bean>
</property>
<property name="targetMethod" value="execute"/>
</bean>
<bean id="fastDateFormat" class="org.apache.commons.lang.time.FastDateFormat" factory-method="getInstance">
<constructor-arg value="dd/MM/yyyy"/>
</bean>
<bean id="currentDate" class="java.util.Date" factory-bean="fastDateFormat" factory-method="format" scope="step">
<constructor-arg>
<bean class="java.util.Date"/>
</constructor-arg>
</bean>
It throws :-
Error creating bean with name 'currentDate' defined in BeanDefinition
defined in file
[/home/nextag/Apache6/tomcat/webapps/nextag/WEB-INF/classes/META-INF/spring/batch/jobs/seller-meta-stats-logging-job.xml]:
Initialization of bean failed; nested exception is
java.lang.IllegalStateException: Cannot create scoped proxy for bean
'scopedTarget.currentDate': Target type could not be determined at the
time of proxy creation.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
However, it works fine in case I use prototype .
Need to ask why it is not working in step scope, am I missing something ?
You need to tell the bean currentDate scope proxy so any injection is only valid to scope step. A good explanation is here
<bean id="fastDateFormat" class="org.apache.commons.lang.time.FastDateFormat" factory-method="getInstance">
<constructor-arg value="dd/MM/yyyy"/>
</bean>
<bean id="currentDate" class="java.util.Date" factory-bean="fastDateFormat" factory-method="format" scope="step">
<aop:scoped-proxy/>
<constructor-arg>
<bean class="java.util.Date"/>
</constructor-arg>
</bean>

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

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.

Is it possible use HashMultimap to create spring bean?

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?

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

Categories