With this example I will show you how compound or nested property names work in Spring application. Compound or nested property names are perfectly legal when setting bean properties, as long as all components of the path except the final property name are non-null.
You can use compound or nested property names when you set bean properties, as long as all components of the path except the final property name are not null.
For example, in this bean definition:
<bean id="foo" class="foo.Bar">
<property name="fred.bob.sammy" value="123"/>
</bean>
the foo bean has a fred property which has a bob property, which has a sammy property, and that final sammy property is being set to a scalar value of 123. In order for this to work, the fred property of foo, and the bob property of fred must both be non-null after the bean is constructed, or a null-pointer exception will be thrown.
Prerequisites
Java at least 8, Spring Boot 2.4.1, Maven 3.6.3, Gradle 6.7.1
Project Setup
You can create a gradle or maven based project in your favorite IDE or tool.
For gradle based project you can use the following build.gradle script:
buildscript {
ext {
springBootVersion = '2.4.1'
}
repositories {
maven {
url 'https://plugins.gradle.org/m2/'
}
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
}
}
plugins {
id 'java-library'
id 'org.springframework.boot' version "${springBootVersion}"
}
sourceCompatibility = 12
targetCompatibility = 12
repositories {
mavenCentral()
jcenter()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter:${springBootVersion}")
}
For maven based project you can use the following pom.xml file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.roytuts</groupId>
<artifactId>spring-compound-property-name</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>12</maven.compiler.source>
<maven.compiler.target>12</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Compound Property Config
Create a source folder src/main/resources if it does not exist already. Create an XML file called compound-property-config.xml with the following content.
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">
<bean id="compoundPropertyName"
class="com.roytuts.spring.compound.property.name.Bar">
<property name="foo.fred.bob.jhon" value="Jhon Rambo" />
</bean>
</beans>
Required Classes
Now you need to create the required classes which has been configured in the above XML config file for compound property names.
Class – Bob
package com.roytuts.spring.compound.property.name;
public class Bob {
private String jhon;
public String getJhon() {
return jhon;
}
public void setJhon(String jhon) {
this.jhon = jhon;
}
}
Class – Fred
package com.roytuts.spring.compound.property.name;
public class Fred {
private Bob bob;
public Fred() {
bob = new Bob();
}
public Bob getBob() {
return bob;
}
public void setBob(Bob bob) {
this.bob = bob;
}
}
Class – Foo
package com.roytuts.spring.compound.property.name;
public class Foo {
private Fred fred;
public Foo() {
fred = new Fred();
}
public Fred getFred() {
return fred;
}
public void setFred(Fred fred) {
this.fred = fred;
}
}
Class – Bar
package com.roytuts.spring.compound.property.name;
public class Bar {
private Foo foo;
public Bar() {
foo = new Foo();
}
public Foo getFoo() {
return foo;
}
public void setFoo(Foo foo) {
this.foo = foo;
}
}
Load XML Config File
You need to load the XML configuration file which was put under the class path folder src/main/resources. So create the below Config Java class to load the XML file using annotation @ImportResource
.
package com.roytuts.spring.compound.property.name;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
@Configuration
@ImportResource("classpath:compound-property-config.xml")
public class Config {
}
Main Class
A class with main method and @SpringBootApplication
annotation is used to start the Spring Boot application. I am using CLI version for starting the app.
I am injecting the ApplicationContext which is easily available in the Spring Boot based application.
package com.roytuts.spring.compound.property.name;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
@SpringBootApplication
public class SpringCompoundPropertyNameApp implements CommandLineRunner {
@Autowired
private ApplicationContext applicationContext;
public static void main(String[] args) {
SpringApplication.run(SpringCompoundPropertyNameApp.class, args);
}
@Override
public void run(String... args) throws Exception {
Bar bar = applicationContext.getBean(Bar.class);
System.out.println(bar.getFoo().getFred().getBob().getJhon());
}
}
Testing the Application
Running the above main class you will see the following output:
Jhon Rambo
That’s all about compound property names in Spring application.