Saturday, December 26, 2020

Injecting Inner Beans in Spring

This post shows how to inject inner beans in Spring and what are the scenarios when you would need to inject a bean as an inner bean.

Let’s say you have a Java class which refers to another class object and the access type for that object is private. In that case what do you think is the best way to provide bean definition in Spring. Let me provide class (Employee.java) here so you can understand what I am saying.

public class Employee {
 private Person person;

 public Person getPerson() {
  return person;
 }

 public void setPerson(Person person) {
  this.person = person;
 }
 
 public String toString(){
  return "Name - " + person.getName() + "Age - " + person.getAge();
 }
}

Here person object is private meaning person is not shared.

Coming to Spring definition, you may use the usual way of defining Employee and Person bean separately and use “ref” attribute to reference Person bean into Employee bean. But, in that case person bean can also be referenced by other beans and that same instance will be shared by all those beans. If you don’t want that to happen better inject Person bean as an inner bean of Employee bean in the Spring configuration.

Spring inner bean

Inner beans in Spring are beans that are defined within the scope of another bean. Defining Person bean as an inner bean of Employee bean will mean that definition of Person bean is restricted with in the scope of Employee bean.

Inner bean can be configured both as setter dependency using property tag and as constructor dependency using constructor-arg.

Injecting inner bean example using property tag

You can configure inner bean to be injected as setter dependency using property tag.

Person Class

public class Person {
 private String name;
 private int age;
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public int getAge() {
  return age;
 }
 public void setAge(int age) {
  this.age = age;
 }
}

XML Configuration

<?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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd">

  <bean id="employeeBean" class="org.netjs.exp.Spring_Example.Employee">
    <property name="person">
      <bean class="org.netjs.exp.Spring_Example.Person">
        <property name="name" value="Ram" />
        <property name="age" value="22" />
      </bean>
    </property>
  </bean>
</beans>

Java class to run application

public class App {
  public static void main( String[] args ){
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext
          ("appcontext.xml");
    Employee employee = (Employee) context.getBean("employeeBean");
    System.out.println("Employee " + employee);
    context.close();
  }
}

Output

Employee Name - RamAge - 22

Here some points to note are-

  1. A Spring inner bean definition does not require a defined id or name; even if you provide container ignores these values.
  2. Inner bean doesn’t have its own scope. If provided container ignores the scope flag.
  3. Inner beans are always anonymous and they are always created with in the scope of outer bean.
  4. It is not possible to inject inner beans into collaborating beans other than into the enclosing bean.

Injecting inner bean example using constructor-arg tag

You can also configure inner bean to be injected as constructor dependency using constructor-arg.

Employee class

Employee class in that case.
public class Employee {
 private Person person;
 // Constructor
 public Employee(Person person) {
  this.person = person;
 }

 public Person getPerson() {
  return person;
 }

 public void setPerson(Person person) {
  this.person = person;
 }
 
 public String toString(){
  return "Name - " + person.getName() + "Age - " + person.getAge(); 
 }
}

XML configuration with constructor-arg property

<?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"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context.xsd">
  
  <bean id="employeeBean" class="org.netjs.exp.Spring_Example.Employee">
    <constructor-arg name="person">
      <bean class="org.netjs.exp.Spring_Example.Person">
        <property name="name" value="Ram" />
        <property name="age" value="22" />
      </bean>
    </constructor-arg>
  </bean>
</beans>

That's all for this topic Injecting Inner Beans in Spring. If you have any doubt or any suggestions to make please drop a comment. Thanks!

>>>Return to Spring Tutorial Page


Related Topics

  1. How to Inject Prototype Scoped Bean in Singleton Bean
  2. Bean Scopes in Spring With Examples
  3. BeanPostProcessor in Spring Framework
  4. Using c-namespace in Spring
  5. Wiring collections in Spring

You may also like-

  1. Spring NamedParameterJdbcTemplate Select Query Example
  2. Autowiring in Spring Using @Autowired and @Inject Annotations
  3. Spring Expression Language (SpEL) With Examples
  4. Lambda Expressions in Java 8
  5. String in Java Tutorial
  6. Check if Given String or Number is a Palindrome Java Program
  7. Encapsulation in Java
  8. Deadlock in Java Multi-Threading

No comments:

Post a Comment