Suppose the bean is Employee
and we want to refer to employee’s company
, we can do it in Java using emp.getCompany()
, assuming emp
is the Employee
bean and company
is Employee
‘s property.
The same can be done in spring by declaring a bean of class org.springframework.beans.factory.config.PropertyPathFactoryBean
with emp
bean as the targetObject
and company
as the propertyPath
.
If you want to declare a bean that evaluates to a property path on a given target object then you need to make use of the built-in factory bean PropertyPathFactoryBean
.
From spring 2.0, this is been simplified by using a custom tag <util:property-path >
.
This example uses the following frameworks:
Dependencies
Add the following dependencies:
spring-core
spring-context
spring-beans
Declare PropertyPathFactoryBean bean
Create an Employee
class with a member variable company
which is of type class Company
. Our goal would be to create an employee bean and declare a bean that refers to the company the employee belongs to.
Employee:
package com.javarticles.spring; public class Employee { private String name; private Company company; public Employee(String name) { this.name = name; } public String getName() { return name; } public Company getCompany() { return company; } public void setCompany(Company company) { this.company = company; } }
Company:
package com.javarticles.spring; public class Company { public Company(String name) { this.name = name; } public String getName() { return name; } public String toString() { return "Company(" + name + ")"; } private String name; }
In the below context XML, we declare an employee bean for ‘Joe’. The company ‘ABC’ he works for is declared as an inner bean. Next, we declare a factory bean PropertyPathFactoryBean
to access the company
property. Since we want to know employee Joe’s company, the targetObject
becomes empJoe
bean and propertyPath
is company
.
It is equivalent to calling empJoe.getCompany()
in Java.
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"> <bean id="empJoe" class="com.javarticles.spring.Employee"> <constructor-arg index="0" value="Joe" /> <property name="company"> <bean class="com.javarticles.spring.Company"> <constructor-arg index="0" value="ABC" /> </bean> </property> </bean> <bean id="empJoeCompany" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> <property name="targetObject" ref="empJoe" /> <property name="propertyPath"> <value>company</value> </property> </bean> </beans>
Let’s run the example and access the declared bean empJoeCompany
.
SpringPropertyPathFactoryBeanExample:
package com.javarticles.spring; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringPropertyPathFactoryBeanExample { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( "applicationContext.xml"); try { Company empJoeCompany = (Company) context.getBean("empJoeCompany"); System.out.println(empJoeCompany); } finally { context.close(); } } }
Output:
Company(ABC)
You can even access the other properties which are part of the object graph, for example, name of the company Joe is working for.
We have declared two new beans empJoeCompanyName1
and empJoeCompanyName2
. In empJoeCompanyName1
, we refer to company object’s name using the propertyPath
‘company.name’.
Bean declaration empJoeCompanyName2
is nearly same as empJoeCompanyName1
with just one difference. We set the targetBeanName
instead of targetObject
. Internally, spring will get the target bean from the bean factory.
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"> <bean id="empJoe" class="com.javarticles.spring.Employee"> <constructor-arg index="0" value="Joe" /> <property name="company"> <bean class="com.javarticles.spring.Company"> <constructor-arg index="0" value="ABC" /> </bean> </property> </bean> <bean id="empJoeCompany" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> <property name="targetObject" ref="empJoe" /> <property name="propertyPath"> <value>company</value> </property> </bean> <bean id="empJoeCompanyName1" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> <property name="targetObject" ref="empJoe" /> <property name="propertyPath"> <value>company.name</value> </property> </bean> <bean id="empJoeCompanyName2" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> <property name="targetBeanName"><value>empJoe</value></property> <property name="propertyPath"> <value>company.name</value> </property> </bean> </beans>
SpringPropertyPathFactoryBeanExample:
package com.javarticles.spring; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringPropertyPathFactoryBeanExample { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( "applicationContext.xml"); try { Company empJoeCompany = (Company) context.getBean("empJoeCompany"); System.out.println(empJoeCompany); System.out.println("Access just the company name"); String empJoeCompanyName = (String) context.getBean("empJoeCompanyName1"); System.out.println("empJoeCompanyName1 value: " + empJoeCompanyName); System.out.println("empJoeCompanyName2 value: " + context.getBean("empJoeCompanyName2")); } finally { context.close(); } } }
Output:
Company(ABC) Access just the company name empJoeCompanyName1 value: ABC empJoeCompanyName2 value: ABC
You can also create a bean ID combining targetObject
and property
using a dot. For example, empJoe.name
, empJoe.company
and empJoe.company.name
.
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"> <bean id="empJoe" class="com.javarticles.spring.Employee"> <constructor-arg index="0" value="Joe" /> <property name="company"> <bean class="com.javarticles.spring.Company"> <constructor-arg index="0" value="ABC" /> </bean> </property> </bean> <bean id="empJoeCompany" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> <property name="targetObject" ref="empJoe" /> <property name="propertyPath"> <value>company</value> </property> </bean> <bean id="empJoeCompanyName1" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> <property name="targetObject" ref="empJoe" /> <property name="propertyPath"> <value>company.name</value> </property> </bean> <bean id="empJoeCompanyName2" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> <property name="targetBeanName"><value>empJoe</value></property> <property name="propertyPath"> <value>company.name</value> </property> </bean> <bean id="empJoe.name" class="org.springframework.beans.factory.config.PropertyPathFactoryBean" /> <bean id="empJoe.company" class="org.springframework.beans.factory.config.PropertyPathFactoryBean" /> <bean id="empJoe.company.name" class="org.springframework.beans.factory.config.PropertyPathFactoryBean" /> </beans>
SpringPropertyPathFactoryBeanExample:
package com.javarticles.spring; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringPropertyPathFactoryBeanExample { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( "applicationContext.xml"); try { Company empJoeCompany = (Company) context.getBean("empJoeCompany"); System.out.println(empJoeCompany); System.out.println("Access just the company name"); String empJoeCompanyName = (String) context.getBean("empJoeCompanyName1"); System.out.println("empJoeCompanyName1 value: " + empJoeCompanyName); System.out.println("empJoeCompanyName2 value: " + context.getBean("empJoeCompanyName2")); System.out.println("empJoe.name value: " + context.getBean("empJoe.name")); System.out.println("empJoe.company value: " + context.getBean("empJoe.company")); System.out.println("empJoe.company.name value: " + context.getBean("empJoe.company.name")); } finally { context.close(); } } }
Output:
Company(ABC) Access just the company name empJoeCompanyName1 value: ABC empJoeCompanyName2 value: ABC empJoe.name value: Joe empJoe.company value: Company(ABC) empJoe.company.name value: ABC
Suppose, we have employees John and Anil working in same company and we want to make use of Anil’s company while declaring John’s employee bean.
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"> <bean id="empJoe" class="com.javarticles.spring.Employee"> <constructor-arg index="0" value="Joe" /> <property name="company"> <bean class="com.javarticles.spring.Company"> <constructor-arg index="0" value="ABC" /> </bean> </property> </bean> <bean id="empJoeCompany" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> <property name="targetObject" ref="empJoe" /> <property name="propertyPath"> <value>company</value> </property> </bean> <bean id="empJoeCompanyName1" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> <property name="targetObject" ref="empJoe" /> <property name="propertyPath"> <value>company.name</value> </property> </bean> <bean id="empJoeCompanyName2" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> <property name="targetBeanName"><value>empJoe</value></property> <property name="propertyPath"> <value>company.name</value> </property> </bean> <bean id="empJoe.name" class="org.springframework.beans.factory.config.PropertyPathFactoryBean" /> <bean id="empJoe.company" class="org.springframework.beans.factory.config.PropertyPathFactoryBean" /> <bean id="empJoe.company.name" class="org.springframework.beans.factory.config.PropertyPathFactoryBean" /> <bean id="empAnil" class="com.javarticles.spring.Employee"> <constructor-arg index="0" value="Anil" /> <property name="company"> <bean class="com.javarticles.spring.Company"> <constructor-arg index="0" value="XYZ" /> </bean> </property> </bean> <bean id="empJohn" class="com.javarticles.spring.Employee"> <constructor-arg index="0" value="John" /> <property name="company"> <bean name="empAnil.company" class="org.springframework.beans.factory.config.PropertyPathFactoryBean" /> </property> </bean> </beans>
SpringPropertyPathFactoryBeanExample:
package com.javarticles.spring; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringPropertyPathFactoryBeanExample { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( "applicationContext.xml"); try { Company empJoeCompany = (Company) context.getBean("empJoeCompany"); System.out.println(empJoeCompany); System.out.println("Access just the company name"); String empJoeCompanyName = (String) context.getBean("empJoeCompanyName1"); System.out.println("empJoeCompanyName1 value: " + empJoeCompanyName); System.out.println("empJoeCompanyName2 value: " + context.getBean("empJoeCompanyName2")); System.out.println("empJoe.name value: " + context.getBean("empJoe.name")); System.out.println("empJoe.company value: " + context.getBean("empJoe.company")); System.out.println("empJoe.company.name value: " + context.getBean("empJoe.company.name")); System.out.println("empAnil's company: " + ((Employee) context.getBean("empAnil")).getCompany()); System.out.println("empJohn's company: " + ((Employee) context.getBean("empJohn")).getCompany()); } finally { context.close(); } } }
Output:
Company(ABC) Access just the company name empJoeCompanyName1 value: ABC empJoeCompanyName2 value: ABC empJoe.name value: Joe empJoe.company value: Company(ABC) empJoe.company.name value: ABC empAnil's company: Company(XYZ) empJohn's company: Company(XYZ)
Spring 2.x allows you to declare a bean using the util:property-path
tag. We have declared bean empJohnNameByPropertyPath
, property path attribute contains the path empJohn.name
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"> <bean id="empJoe" class="com.javarticles.spring.Employee"> <constructor-arg index="0" value="Joe" /> <property name="company"> <bean class="com.javarticles.spring.Company"> <constructor-arg index="0" value="ABC" /> </bean> </property> </bean> <bean id="empJoeCompany" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> <property name="targetObject" ref="empJoe" /> <property name="propertyPath"> <value>company</value> </property> </bean> <bean id="empJoeCompanyName1" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> <property name="targetObject" ref="empJoe" /> <property name="propertyPath"> <value>company.name</value> </property> </bean> <bean id="empJoeCompanyName2" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"> <property name="targetBeanName"><value>empJoe</value></property> <property name="propertyPath"> <value>company.name</value> </property> </bean> <bean id="empJoe.name" class="org.springframework.beans.factory.config.PropertyPathFactoryBean" /> <bean id="empJoe.company" class="org.springframework.beans.factory.config.PropertyPathFactoryBean" /> <bean id="empJoe.company.name" class="org.springframework.beans.factory.config.PropertyPathFactoryBean" /> <bean id="empAnil" class="com.javarticles.spring.Employee"> <constructor-arg index="0" value="Anil" /> <property name="company"> <bean class="com.javarticles.spring.Company"> <constructor-arg index="0" value="XYZ" /> </bean> </property> </bean> <bean id="empJohn" class="com.javarticles.spring.Employee"> <constructor-arg index="0" value="John" /> <property name="company"> <bean name="empAnil.company" class="org.springframework.beans.factory.config.PropertyPathFactoryBean" /> </property> </bean> <util:property-path id="empJohnNameByPropertyPath" path="empJohn.name"/> </beans>
SpringPropertyPathFactoryBeanExample:
package com.javarticles.spring; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringPropertyPathFactoryBeanExample { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( "applicationContext.xml"); try { Company empJoeCompany = (Company) context.getBean("empJoeCompany"); System.out.println(empJoeCompany); System.out.println("Access just the company name"); String empJoeCompanyName = (String) context.getBean("empJoeCompanyName1"); System.out.println("empJoeCompanyName1 value: " + empJoeCompanyName); System.out.println("empJoeCompanyName2 value: " + context.getBean("empJoeCompanyName2")); System.out.println("empJoe.name value: " + context.getBean("empJoe.name")); System.out.println("empJoe.company value: " + context.getBean("empJoe.company")); System.out.println("empJoe.company.name value: " + context.getBean("empJoe.company.name")); System.out.println("empAnil's company: " + ((Employee) context.getBean("empAnil")).getCompany()); System.out.println("empJohn's company: " + ((Employee) context.getBean("empJohn")).getCompany()); System.out.println("empJohnNameByPropertyPath: " + context.getBean("empJohnNameByPropertyPath")); } finally { context.close(); } } }
Output:
Company(ABC) Access just the company name empJoeCompanyName1 value: ABC empJoeCompanyName2 value: ABC empJoe.name value: Joe empJoe.company value: Company(ABC) empJoe.company.name value: ABC empAnil's company: Company(XYZ) empJohn's company: Company(XYZ) empJohnNameByPropertyPath: John
Download the source code
This was an example about spring’s factory bean PropertyPathFactoryBean.