Thursday, 2 August 2018

How to inject the inner bean in spring using Constructor dependency Injection

Enjoying This Tutorial?

Subscribe to Ram N Java for high-quality, practical Java and Spring tutorials!

SUBSCRIBE NOW

Introduction

In the Spring Framework, beans are typically defined at the top level and referenced across your configuration. However, when a dependent bean is meant exclusively for one enclosing bean and should never be accessed or shared anywhere else, Spring allows you to define it as an Inner Bean directly inside a <constructor-arg> element.

Why Use Inner Beans with Constructor Injection?

  • Encapsulation: Inner beans do not require an id or name attribute; even if provided, the container ignores it and prevents other beans from referencing it.
  • Immutability & Safety: Using constructor injection guarantees that the enclosing bean is instantiated only when its dependent inner bean is fully ready.
  • Cleaner XML: Avoids cluttering your XML context file with top-level helper bean declarations that are only used in a single place.

Step-by-Step Configuration Example

Consider an Employee class that requires an Address object via its constructor. Here is how you configure the Address as an inner bean inside applicationContext.xml:

1. Defining the Inner Bean in XML

<bean id="employee" class="com.ram.model.Employee">
    <constructor-arg value="101" />
    <constructor-arg value="Peter" />
    <constructor-arg>
        <!-- Inner Bean Definition -->
        <bean class="com.ram.model.Address">
            <property name="city" value="New York" />
            <property name="state" value="NY" />
            <property name="country" value="USA" />
        </bean>
    </constructor-arg>
</bean>

2. Executing with ApplicationContext

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

Employee emp = (Employee) context.getBean("employee");
emp.displayEmployeeInfo();

Key Takeaway

An inner bean always shares the lifecycle of its outer bean. It is created together with the parent bean and cannot be retrieved independently via context.getBean(). This pattern is ideal for tightly-coupled component dependencies.


Click here to watch on Youtube:
https://www.youtube.com/watch?v=Qo6hY0Mei-E&list=UUhwKlOVR041tngjerWxVccw

Click the below Image to Enlarge:
How to inject the inner bean in spring using Constructor dependency Injection

How to inject the inner bean in spring using Constructor dependency Injection

How to inject the inner bean in spring using Constructor dependency Injection


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%20http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.ram.core</groupId>
    <artifactId>SpringDemo</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>SpringDemo</name>
    <url>http://maven.apache.org</url>

    <properties>
        <spring.version>5.0.2.RELEASE</spring.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <!-- Spring 5 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>
</project>

Address.java

package com.ram.model;

public class Address
{
    private String city;
    private String state;

    public String getCity()
    {
        return city;
    }

    public void setCity(String city)
    {
        this.city = city;
    }

    public String getState()
    {
        return state;
    }

    public void setState(String state)
    {
        this.state = state;
    }

    @Override
    public String toString()
    {
        return "Address [city=" + city + ", state=" + state + "]";
    }

}

Employee.java

package com.ram.model;

public class Employee
{
    private int id;
    private String name;
    private Address address;

    public Employee(int id, String name, Address address)
    {
        this.id = id;
        this.name = name;
        this.address = address;
    }

    @Override
    public String toString()
    {
        return "Employee [id=" + id + ", name=" + name + ", address=" + address
                + "]";
    }

}

applicationContext.xml

<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-4.3.xsd">


    <bean id="employee" class="com.ram.model.Employee">

        <constructor-arg type="int" value="36"></constructor-arg>
        <constructor-arg type="String" value="Peter"></constructor-arg>

        <constructor-arg>
            <bean class="com.ram.model.Address">
                <property name="city" value="TamilNadu"></property>
                <property name="state" value="Chennai"></property>
            </bean>
        </constructor-arg>

    </bean>

</beans>

App.java

package com.ram.core;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.ram.model.Employee;

public class App
{
    public static void main(String[] args)
    {
        ApplicationContext context = new ClassPathXmlApplicationContext(
                "applicationContext.xml");

        System.out.println("-------------------------------------------");

        Employee employee = (Employee) context.getBean("employee");
        System.out.println(
                "Got employee object from the ApplicationContext(Spring Container)");

        System.out.println(employee);

    }

}

Output

Jul 15, 2018 6:50:16 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5b37e0d2: startup date [Sun Jul 15 06:50:16 IST 2018]; root of context hierarchy
Jul 15, 2018 6:50:16 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [applicationContext.xml]
-------------------------------------------
Got employee object from the ApplicationContext(Spring Container)
Employee [id=36, name=Peter, address=Address [city=TamilNadu, state=Chennai]]

Click the below link to download the code:
https://sites.google.com/site/ramj2eev2/java_basics/SpringDemo_Innerbean_constructor_injection.zip?attredirects=0&d=1

Github Link:
https://github.com/ramram43210/javaee/tree/master/Spring_2018/SpringDemo_Innerbean_constructor_injection

Bitbucket Link:
https://bitbucket.org/ramram43210/spring/src/42c66b7d9692a3dc3e770c804733a8013c61553b/Spring_2018/SpringDemo_Innerbean_constructor_injection/?at=master

See also:

  • All JavaEE Videos Playlist
  • All JavaEE Videos
  • All JAVA EE Links
  • Spring Tutorial
  • Servlets Tutorial
  • All Design Patterns Links
  • JDBC Tutorial
  • Java Collection Framework Tutorial
  • JAVA Tutorial
  • Kids Tutorial
  • Cooking Tutorial
  • No comments:

    Post a Comment

    Tutorials