Spring PropertyPathFactoryBean Example

0

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:

  1. Maven 3.2.3
  2. Spring 4.1.5.RELEASE
  3. Eclipse  as the IDE, version Luna 4.4.1.

Dependencies

Add the following dependencies:

  1. spring-core
  2. spring-context
  3. 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.

You can download the source code here: springPropertyPathExample.zip
Share.

Comments are closed.