Occasionally, Spring can't figure out what type a "value" should be. This happens when the property or constructor is of type "java.lang.Object". In these cases, Spring defaults to "java.lang.String". Sometimes this isn't the right choice, for example when using:
<jee:jndi-lookup id="test" jndi-name="java:comp/env/test"
default-value="10" expected-type="java.lang.Integer"/>
If the lookup fails and it has to fall back to the default-value, there's a type mismatch. So, instead, this needs to be done:
<bean id="test" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/test" />
<property name="defaultObject">
<bean class="java.lang.Integer">
<constructor-arg value="10" />
</bean>
</property>
</bean>
which is somewhat verbose, especially if there are lots of them. Is there some handy way to declare an Integer / Long / Double / Float / String literal without having to use this format:
<bean class="java.lang.Integer">
<constructor-arg value="10" />
</bean>
Since Spring 3.0, you can use Spring Expression Language: #{new Integer(10)}
<jee:jndi-lookup id="test" jndi-name="java:comp/env/test"
default-value="#{new Integer(10)}" expected-type="java.lang.Integer"/>
You should be able to do:
<constructor-arg value="10" type="int"/>
See section 3.3.1.1.1.1 of the Spring Reference
Related
Here's what I am trying to do. I have a spring batch job which triggers a bean with multiple properties. I want these properties to be divided into separate beans for organizational purposes.
So I currently have this:
<bean id="runSQL" class="Tasklet"
scope="step">
<property name="sourceSQL"
value="SQL STATEMENT HERE" />
<property name="targetSQL"
value="SQL STATEMENT HERE"></property>
<property name="filePath" value="#{jobParameters['OUTPUT.FILE.PATH']}"> </property>
</bean>
but I basically want this (not working due to lack of class definition and I don't know if #{souce.sourceSQL} is a valid way of grabbing bean properties):
<bean id="runSQL" class="Tasklet"
scope="step">
<property name="sourceSQL"
value="#{source.sourceSQL}" />
<property name="targetSQL"
value="#{target.targetSQL}"></property>
<property name="filePath" value="#{jobParameters['OUTPUT.FILE.PATH']}"> </property>
</bean>
<bean id="sourceSQL" class="Class not needed"
scope="step">
<property name="sourceSQL"
value="SQL STATEMENT HERE" />
</property>
</bean>
<bean id="targetSQL" class="Class not needed"
scope="step">
<property name="sourceSQL"
value="SQL STATEMENT HERE" />
</property>
</bean>
I have tried to reference the beans traditionally with
<ref bean="someBean"/>
but my Tasklet isn't designed to receive a bean, just the property values and I would prefer to leave the Tasklet as is. How do I get around this or alternative ways of storing this data for the beans?
You're on the right track with #{...}. If you want to reference a bean, stick a # in front of the Spring bean ID, for example #{#sourceSQL.sourceSQL} and #{#targetSQL.sourceSQL}.
See the documentation for the Spring Expression language.
i am currently using MappingJacksonHttpMessageConverter in my Dispatcher-Servlet.xml. In my application when the user enters a currency, commas are itself attached to the value. When that value is passed to the controller it is unable to convert the string with commas to a double value. throws pare error. I am using this value for other calculations so i cannot change its type to string in the modal class.
Is there a way we can can use MappingJacksonHttpMessageConverter to make the controller ignore the commas and read the value.
This is part of my servlet.xml file.
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="order" value="1" />
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean class="org.springframework.http.converter.FormHttpMessageConverter"/>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter"/>
<bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
</list>
</property>
</bean>
Any help would be appreciated
You can do this by creating custom conversion service in spring by implementing Converter interface.
For info on this see http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/validation.html
and
http://log4aj.blogspot.in/2012/08/spring-converterconversionservice.html.
I would like to configure number of consumers for a single queue in jms template. I tried to implement this: JmsTemplate - define concurrency per queue? but in the ActiveMQQueue is stiil shows 1.
my messanging context:
<bean id="parentContainer" abstract="true"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<bean id="parentContainer" abstract="true"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<bean id="playerStatsListener" parent="parentContainer">
<property name="destination" ref="playerStatsQueue" />
<property name="messageListener" ref="playerStatsService" />
<property name="concurrency" value="100" />
</bean>
<!-- Listeners -->
<bean id="playerStatsService" class="com.XXX.service.PlayerStatsService" />
<!-- Destinations -->
<bean id="playerStatsQueue" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg value="playerStatsQueue" />
another related question: Is there a difference between the "listener" to "messageListener" property?
In general, you can set concurrentConsumers and maxConcurrentConsumers on the DefaultMessageListenerContainer. The concurrency setting gives this as a convenient range.
But according to the docs
Specify concurrency limits via a "lower-upper" String, e.g. "5-10", or
a simple upper limit String, e.g. "10" (the lower limit will be 1 in
this case).
So if you just say concurrency=100, it's still equivalent to 1-100, which would explain why you're seeing 1 consumer.
I need to define a string value in Spring context XML file that is shared by multiple beans.
This is how I do it:
<bean id="aSharedProperty" class="java.lang.String">
<constructor-arg type="java.lang.String" value="All beans need me :)"/>
</bean>
Creating a java.lang.String bean by passing a constructor argument of java.lang.String seems kludgy.
Is there a shortcut?
I know this property can be passed using PropertyOverrideConfigurer, but I want to keep this property within the XML file.
You can use PropertyPlaceholderConfigurer and keep values in xml:
<context:property-placeholder properties-ref="myProperties"/>
<bean id="myProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="properties">
<props>
<prop key="aSharedProperty">All beans need me :)</prop>
</props>
</property>
</bean>
Then you reference it with:
<bean id="myBean" class="my.package.MyClass">
<property name="someField" value="${aSharedProperty}"/>
</bean>
A shorthand to the solution proposed by mrembisz goes like this:
<context:property-placeholder properties-ref="myProperties"/>
<util:properties id="myProperties">
<prop key="aSharedProperty">All beans need me :)</prop>
</util:properties>
You may be able to use the following:
<bean id="abstractParent" abstract="true">
<property name="sharedProperty" value="All child beans need me" />
</bean>
<bean id="bean1" class="MyClass1" parent="abstractParent">
...non-shared properties...
</bean>
<bean id="bean2" class="MyClass2" parent="abstractParent">
...non-shared properties...
</bean>
However, that relies on the property having the same name, so may not be applicable for you.
Something I've used in the past is SpEL to make sure that a bean has the same value as another:
<bean id="myBean" class="xxx.yyy.Foo" >
<property name="myProperty" value="1729" />
</bean>
<bean id="copyCat" class="xxx.yyy.Bar" >
<property name="anotherProperty" value="#{myBean.myProperty}" />
</bean>
I have found this to be particularly useful when setting the value did something other than a simple assignment.
This is the example from the spring 3.0 reference:
<bean id="numberGuess" class="org.spring.samples.NumberGuess">
<property name="randomNumber" value="#{ T(java.lang.Math).random() * 100.0 }"/>
</bean>
<bean id="shapeGuess" class="org.spring.samples.ShapeGuess">
<property name="initialShapeSeed" value="#{ numberGuess.randomNumber }"/>
</bean>
But what I intend to do is something like this:
<bean id="foo" class="com.example.Foo">
<property name="name" value="myName"/>
<property name="prop">
<bean class="com.example.Bar">
<property name="#{ parent.name }" />
</bean>
</property>
</bean>
So the property name of the inner bean is populated with the name of the outer bean. Is this possible with the spring expression language at all? What would be the expression for something like this (parent clearly doesn't work ^^)?
I don't think that's possible in the given milestone build. They're still taking feature requests for RC1, though, so I suggest filing one.