Spring Inner Bean Example
This is an example of how to use an inner Bean definition inside a Bean. In Spring 3.2.3, when a bean is only used as a property of another bean it can be declared as an inner bean. Spring’s XML-based configuration metadata provides the use of <bean/>
element inside the <property/>
or <constructor-arg/>
elements of a bean definition, in order to define the so-called inner bean.
Our preferred development environment is Eclipse. We are using Eclipse Juno (4.2) version, along with Maven Integration plugin version 3.1.0. You can download Eclipse from here and Maven Plugin for Eclipse from here. The installation of Maven plugin for Eclipse is out of the scope of this tutorial and will not be discussed. We are also using Spring version 3.2.3 and the JDK 7_u_21.
Let’s begin.
1. Create a new Maven project
Go to File -> Project ->Maven -> Maven Project.
In the “Select project name and location” page of the wizard, make sure that “Create a simple project (skip archetype selection)” option is checked, hit “Next” to continue with default values.
In the “Enter an artifact id” page of the wizard, you can define the name and main package of your project. We will set the “Group Id” variable to "com.javacodegeeks.snippets.enterprise"
and the “Artifact Id” variable to "springexample"
. The aforementioned selections compose the main project package as "com.javacodegeeks.snippets.enterprise.springexample"
and the project name as "springexample"
. Hit “Finish” to exit the wizard and to create your project.
The Maven project structure is shown below:
- It consists of the following folders:
- /src/main/java folder, that contains source files for the dynamic content of the application,
- /src/test/java folder contains all source files for unit tests,
- /src/main/resources folder contains configurations files,
- /target folder contains the compiled and packaged deliverables,
- the pom.xml is the project object model (POM) file. The single file that contains all project related configuration.
2. Add Spring 3.2.3 dependency
- Locate the “Properties” section at the “Overview” page of the POM editor and perform the following changes:
Create a new property with name org.springframework.version and value 3.2.3.RELEASE. - Navigate to the “Dependencies” page of the POM editor and create the following dependencies (you should fill the “GroupId”, “Artifact Id” and “Version” fields of the “Dependency Details” section at that page):
Group Id : org.springframework Artifact Id : spring-web Version : ${org.springframework.version}
Alternatively, you can add the Spring dependencies in Maven’s pom.xml
file, by directly editing it at the “Pom.xml” page of the POM editor, as shown below:
pom.xml:
<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.javacodegeeks.snippets.enterprise</groupId> <artifactId>springexample</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> </dependencies> <properties> <spring.version>3.2.3.RELEASE</spring.version> </properties> </project>
As you can see Maven manages library dependencies declaratively. A local repository is created (by default under {user_home}/.m2 folder) and all required libraries are downloaded and placed there from public repositories. Furthermore intra – library dependencies are automatically resolved and manipulated.
3. Create a simple Spring Bean with an inner bean
We create a simple Spring Bean, that is HelloWorld
, and has one property, that is another bean, Foo
.
HelloWorld.java:
package com.javacodegeeks.snippets.enterprise.services; public class HelloWorld { private Foo foo; public void setFoo(Foo foo) { this.foo = foo; } public String toString(){ return "HelloWorld! \n" + foo; } }
The inner bean Foo
is the one below:
Foo.java:
package com.javacodegeeks.snippets.enterprise.services; public class Foo { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString(){ return "I am " + name + " of inner bean foo."; } }
4. XML-based approach for inner bean
Usually, when a bean is used by another bean, the common way to declare it inside the other bean definition by using the <ref>
attribute, as mentioned in a previous example. But when the bean is only used as a property to another bean, then it can be used as an inner bean and is only declared as a property of the other bean. Here, fooBean
is only used by helloWorldBean
, so it is an inner bean of helloWorldBean
.
The inner bean is supported both in setter injection <property/>
and constructor injection <constructor-arg>
elements.
4.1 Using setter injection <property/> element
With setter injection in helloWorldBean
, fooBean
is defined in the <property/>
element, as shown below:
HelloWorld.java:
package com.javacodegeeks.snippets.enterprise.services; public class HelloWorld { private Foo foo; public void setFoo(Foo foo) { this.foo = foo; } public String toString(){ return "HelloWorld! \n" + foo; } }
applicationContext.xml:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd"> <bean id="helloWorldBean" class="com.javacodegeeks.snippets.enterprise.services.HelloWorld"> <property name="foo"> <bean class="com.javacodegeeks.snippets.enterprise.services.Foo"> <property name="name" value="fooName"/> </bean> </property> </bean> </beans>
4.2 Using constructor injection <constructor-arg>
With constructor injection, the inner bean is defined in the <constructor-arg>
element, as shown below:
HelloWorld.java:
package com.javacodegeeks.snippets.enterprise.services; public class HelloWorld { private Foo foo; public HelloWorld(Foo foo) { this.foo = foo; } public void setFoo(Foo foo) { this.foo = foo; } public String toString(){ return "HelloWorld! \n" + foo; } }
applicationContext.xml:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd"> <bean id="helloWorldBean" class="com.javacodegeeks.snippets.enterprise.services.HelloWorld"> <constructor-arg> <bean class="com.javacodegeeks.snippets.enterprise.services.Foo"> <property name="name" value="fooName" /> </bean> </constructor-arg> </bean> </beans>
Note that, in both cases the inner bean definition does not require a defined id
or name
. The container ignores these values. Inner beans are always anonymous and they are always created with the outer bean. It is not possible to inject inner beans into collaborating beans other than into the enclosing bean.
5. Run the application
Through the ApplicationContext
the beans are loaded to App.class
.
App.java:
package com.javacodegeeks.snippets.enterprise; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.javacodegeeks.snippets.enterprise.services.HelloWorld; public class App { @SuppressWarnings("resource") public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); HelloWorld helloWorld = (HelloWorld) context.getBean("helloWorldBean"); System.out.println(helloWorld); } }
6. Output
When you execute the application you should see something like the output presented below:
HelloWorld!
I am fooName of inner bean foo.
This was an example of how to use an inner Bean definition inside a Bean in Spring 3.2.3.
Download the Eclipse project of this part : SpringInnerBean.zip