Spring Inner Bean Injection

A bean defined within the context of another bean is called a spring inner bean. It is similar to the concept of inner classes in java. e.g. In an ATM (Automated Teller Machine) system, it is possible for the Printer bean to be defined as an inner bean of ATM class.
Github – Source Code for this example

Characteristics of Spring inner bean

The following are the typical characteristics of Spring inner beans:

  • When a bean does not need to be shared with other beans, then it can optionally be declared as an inner bean. Inner bean cannot be injected into any other bean except for the enclosing bean.
  • Inner bean is defined within the context of its enclosing bean
  • Inner bean typically does not have an id associated with it although it is perfectly legal to provide an id. This is because, by its very definition, inner bean will not be shared outside of its enclosing bean. The value of the id attribute of an inner bean
    is ignored by Spring.
  • Defining an inner bean does not imply that it should be defined as an inner class e.g. Printer bean is defined as inner bean but Printer class is not an inner class.
  • The scope of an inner bean is always prototype. Spring will ignore the value of the scope attribute of an inner bean

Limitations of Spring inner bean

The following are some of the limitations of using spring inner beans:

  • Spring Inner beans cannot be reused/shared with other beans
  • In practice, defining inner beans affects the readability of Spring configuration XML

Trail Tip: Use Spring inner beans minimally in your application.
The following sample program provides an overview of usage of Spring inner bean

Spring Inner Bean example

In the sample program, we will create an ATM class and Printer class. As the Printer class is not referenced anywhere outside of the ATM class we will declare Printer bean as an inner bean (inside the enclosing ATM bean). The ATM.printBalanceInformation() method delegates the call to Printer.printBalanceInformation() method.
Also, the Printer bean will be declared as an inner bean and will be injected into ATM bean using setter injection.

Note: Although in this sample program we are using setter injection, it is also possible to declare inner beans using constructor injection.
Finally, we will test our setup using TestSpringInnerBeanInjection class which will load Spring context and call the ATM.printBalanceInformation() method to verify that setter injection using inner bean declarations has happened successfully.

Source Code for Spring Inner Bean example

Create the ATM class with a dependency on Printer class. The ATM class delegates the call to print the balance information to the Printer class (see line 15 below).

           
 package com.studytrails.tutorials.springinnerbeaninjection;

 public class ATM {
     private Printer printer;
     public Printer getPrinter() {
         return printer;
     }
     public void setPrinter(Printer printer) {
         this.printer = printer;
     }

     public void printBalanceInformation(String accountNumber) {
         getPrinter().printBalanceInformation(accountNumber);
     }

}

Create a Printer class with a method printBalanceInformation() (see line 5 below)

            
package com.studytrails.tutorials.springinnerbeaninjection;

public class Printer {

     public void printBalanceInformation(String accountNumber) {
          System.out.println("The printer has printed the balance information for the account number " + accountNumber);
     }

}

Declare the ATM class in spring-config.xml (see line 10 below).

Declare the printer property of ATM class for setter injection (see line 11 below)

Also declare the Printer bean as an inner bean (see line 12 below). As Printer bean has been declared inside the enclosing ATM bean, it is an inner bean. Note that no id attribute has been provided for the Printer bean as it cannot be used outside the context of ATM bean.





      
          
       



Finally, we need a java program to test our setup. This is done by TestSpringInnerBeanInjection.java (see source code below).
We need to tell Spring framework to use the ‘spring-config.xml’ to load our beans(see line 11 below).
We get the reference to ATM class through Spring using the bean name ‘atm’ (see line 12 below). In this step, Spring will resolve the dependency on Printer class (declared as an inner bean) by injecting it using setter injection.
We call the printBalanceInformation() on ATM class (see line 14 below) with some accountNumber (see line 13 below). We will verify that the call is delegated to Printer.printBalanceInformation() method successfully implying the inner bean injection has happened successfully.

package com.studytrails.tutorials.springinnerbeaninjection;

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

public class TestSpringInnerBeanInjection {

 public static void main(String[] args) {
    System.out.println("************** BEGINNING PROGRAM **************");

    ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
    ATM atm = (ATM)context.getBean("atm");
    String accountNumber = "AC5645786";
    atm.printBalanceInformation(accountNumber);

    System.out.println("************** ENDING PROGRAM **************");
  }
}

Leave a Comment