Monday, 17 October 2016

Injecting inner bean in Spring

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) 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 reference by other beans and that same instance will be shared by all those beans. If you don’t want that to happen better use Person bean as an inner bean of Employee bean.

Note that inner beans 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.

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 ){
     //AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
     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. An 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.

Using with constructor-arg

In place of bean, constructor-arg property can also be used.

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 bean in Spring. If you have any doubt or any suggestions to make please drop a comment. Thanks!


Related Topics

  1. How to inject prototype scoped bean in singleton bean
  2. Different bean scopes in Spring
  3. What is Dependency Injection in Spring
  4. Dependency Injection using factory-method in Spring
  5. Wiring collections in Spring

You may also like -

>>>Go to Spring tutorial page

No comments:

Post a Comment