Consider this simple example -
public class Person
{
private String name;
private Date dateOfBirth;
// getters and setters here...
}
In order to initialize Person as a Spring bean, I can write the following.
<bean id = "Michael" class = "com.sampleDomainName.Person">
<property name = "name" value = "Michael" />
</bean>
But in the above bean definition, how can I set the dateOfBirth?
For eg. I want to set the dateOfBirth as
1998-05-07
Treat it like any other POJO (which is is)
<property name="dateOfBirth">
<bean class="java.util.Date" />
</property>
If you need to use an explicit value (such as 1975-04-10), then simply call one of the other constructors (although those which take year-month-day are deprecated). You could also use an explicit java.beans.PropertyEditor which Spring rolls with already (see section 6.4.2; note that you can write your own editors and register them for your own types). You need to register the CustomEditorConfigurer in your config:
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Date"
value="org.springframework.beans.propertyeditors.CustomDateEditor"/>
</map>
</property>
</bean>
Then your data looks like:
<property name="dateOfBirth" value="1975-04-10" />
I might add that Date is not an appropriate data type to store a date-of-birth because Date is really an instant-in-time. You might like to look at Joda and use the LocalDate class.
One of the answers mentioned here is useful, but it needs additional information. The constructor arguments for the CustomDateEditor need to be supplied.
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="java.util.Date"> <ref local = "customDateEditor" />
</entry>
</map>
</property>
</bean>
<bean id = "customDateEditor" class="org.springframework.beans.propertyeditors.CustomDateEditor">
<constructor-arg>
<bean class="java.text.SimpleDateFormat">
<constructor-arg value="yyyy-MM-dd" />
</bean>
</constructor-arg>
<constructor-arg value="true" />
</bean>
Now we can do
<property name="dateOfBirth" value="1998-05-07" />
Spring inject Date into bean property – CustomDateEditor
This paper give two suggestions:
Factory bean
CustomDateEditor
I suggest the "Factory Bean" because the CustomDateEditor is not supported in Spring 4.0+ and the Factory Bean is easy enough to use.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="dateFormat" class="java.text.SimpleDateFormat">
<constructor-arg value="yyyy-MM-dd" />
</bean>
<bean id="customer" class="com.mkyong.common.Customer">
<property name="date">
<bean factory-bean="dateFormat" factory-method="parse">
<constructor-arg value="2010-01-31" />
</bean>
</property>
</bean>
</beans>
Use a CustomDateEditor. It's been in Spring since the early days.
Related
I need to inject a java.sql.Time object into a Subject bean using xml based dependency injection.
This is my Subject class definition.
public class Subject{
private java.sql.Time startedTime;
}
In Java code this will be the way to do it.
Subject subject = new Subject();
Time startedTime = Time.valueOf("HH:MM:SS");
subject.setStartedTime(startedTime);
But now I need to do the same injecting that Time object in the Subject bean via xml
<bean id="startedTime" class="mx.com.project.Subject">
<property name="startedTime">
<!-- java.sql.Time injection-->
</property>
</bean>
I've been looking for a while on the internet but have not found any example on this. Just one to inject a Date property into a Customer object by converting a formatted string "yyyy-MM-dd" to a Date object using SimpleDateFormat.parse("yyyy-MM-dd")
It makes me think there should be a similar way to convert a String to Time object. This is the example I found.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="dateFormat" class="java.text.SimpleDateFormat">
<constructor-arg value="yyyy-MM-dd" />
</bean>
<bean id="customer" class="com.mkyong.common.Customer">
<property name="date">
<bean factory-bean="dateFormat" factory-method="parse">
<constructor-arg value="2010-01-31" />
</bean>
</property>
</bean>
</beans>
By the way, the link to the above example
Perform the conversion from String to Time in your object.
public class Subject
{
private java.sql.Time startedTime;
// blah. your stuff.
public void setStartedTimeValue(final String startedTimeValue)
{
startedTime = Time.valueof(startedTimeValue);
}
}
<bean id="startedTime" class="mx.com.project.Subject">
<property name="startedTimeValue" value="20:14:37"/>
</bean>
The first right answer to this question.
<property name="startedTime">
<bean factory-method="valueOf" class="java.sql.Time">
<constructor-arg value="16:00:00" />
</bean>
</property>
I have a java.util.Properties object which has few key value pairs in it. I am trying to use this Property object in the spring configuration file i.e. define the key in the spring config and during runtime, it should get the value from the properties object.
For ex:
<bean id="test" class="com.sample.Test">
<constructor-arg value="${PROPERTY_KEY} />
</bean>
Now during the runtime, the constructor should get the value that is present in the Property object.
Is there a way to get this done ?
Note: I do not want to use config.properties here. Looking to use java.util.Properties
Thanks,
Rahul
<context:property-placeholder location="classpath:placeholder.properties"/>
or
<bean id="properties"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:<file-name>.properties" />
</bean>
First you have to create bean to access your property file, like below
<bean id="appProperties"
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="singleton" value="true" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<value>classpath*:localhost-mysql.properties</value>
<value>classpath*:mail-server.properties</value>
</list>
</property>
</bean>
<bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" ref="appProperties" />
</bean>
Next you can access Key-Value pair from your property files, like below
<bean id="mailServerSettings" class="com.ratormonitor.app.context.EmailSettings">
<property name="host" value="${mail.server.host}" />
<property name="port" value="${mail.server.port}" />
<property name="username" value="${mail.server.username}" />
<property name="password" value="${mail.server.password}" />
<property name="requestContextPath" value="${request.context.path}" />
</bean>
Hope this code will solve your problem.
You can use Spring Expression Language (SpEL) to get a java object value in spring configuration xml file.
An example :
<property name="misfireInstruction"
value="#{T(org.quartz.CronTrigger).MISFIRE_INSTRUCTION_FIRE_ONCE_NOW}"/>
So this is how I did:
As I said I had a java.util.Properties object. I then created a CustomProperty class which extended PropertySource>
public class CustomPropertySource extends PropertySource<Map<String, Object>>
Then in my main class I did the following:
AbstractApplicationContext context = new ClassPathXmlApplicationContext(new String[] {springConfigLocation, false);
context.getEnvironment().getPropertySources.addlast(new CustomPropertySource("custom", propertiesObject));
conext.refresh();
And then in the spring config file, I had to add this:
<context: property-placeholder ignore-unresolvable="true"/>
So in this way, I could fetch values for the keys defined in the spring config file, just like how we get the values from property files.
Thanks,
Rahul
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.
Short question: If I have class that impelemnts FactoryBean interface, how can I get from FactoryBean object itself instead of FactoryBean.getObject()?
Long question: I have to use 3-rd party Spring based library which is hardly use FactoryBean interface. Right now I always must configure 2 beans:
<!-- Case 1-->
<bean id="XYZ" class="FactoryBean1" scope="prototype">
<property name="steps">
<bean class="FactoryBean2">
<property name="itemReader" ref="aName"/>
</bean>
</property>
</bean>
<bean id="aName" class="com.package.ClassName1" scope="prototype">
<property name="objectContext">
<bean class="com.package.ABC"/>
</property>
</bean>
<!-- Case 2-->
<bean id="XYZ2" class="FactoryBean1" scope="prototype">
<property name="steps">
<bean class="FactoryBean2">
<property name="itemReader" ref="aName2"/>
</bean>
</property>
</bean>
<bean id="aName2" class="com.package.ClassName1" scope="prototype">
<property name="objectContext">
<bean class="com.package.QWE"/>
</property>
</bean>
Actyually defintion of a bean with name "XYZ" (compare with "XYZ2") never will be changed, but because of factory nature I must copy the code for each configuration.
Definition of a bean with name "aName" always will be new (i.e. each configuration will have own objectContext value).
I would like to simplify the configuration have a single factory bean (remove "XYZ2" and rid of link to "aName"):
<bean id="XYZ" class="FactoryBean1" scope="prototype">
<property name="steps">
<bean class="FactoryBean2"/>
</property>
</bean>
<bean id="aName" class="com.package.ClassName1" scope="prototype">
<property name="objectContext">
<bean class="com.package.ABC"/>
</property>
</bean>
<bean id="aName2" class="com.package.ClassName1" scope="prototype">
<property name="objectContext">
<bean class="com.package.QWE"/>
</property>
</bean>
Unfortunately, it's not as simple as I expect. I suppose to glue factory (i.e. XYZ bean from the example) with necessary objects (i.e. "aName", "aName2") at runtime.
The approach doesn't work because when I ask Spring for FactoryBean object it returns to me FactoryBean.getObject() which impossible to instanciate at that time because of missing itemReader value.
I hope that SpringSource foresee my case I can somehome "hook" FactoryBean.getObject() call to provide all necessary properties at runtime.
Another complexity that disturb me a bit it's chains of Factories (Factory1 get an object from Factory2 that I have to "hook" at runtime).
Any ideas will be appreciated.
It's the & (ampersand), not the At-symbol, see Spring Framework documentation: Customizing instantiation logic using FactoryBeans
<property name="factoryBean" ref="&theFactoryBean" />
You can get the factory bean itself using the & syntax in the spring config:
<property name="factoryBean" ref="&theFactoryBean" />
as opposed to:
<property name="createdBean" ref="theFactoryBean" />
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>