Spring beans definition

Let us start with a real world example. One fine day Mr. XYZ thought to writing a book. He chooses his favourite topic of Spring framework and decided the title of the book as “My First Spring Book”.  To start with he decided to write two chapters with title “Spring framework - Chapter 1” and “Spring framework - Chapter 2”.  Java implementation of this scenario will need a java class Title with an instance variable titleValue. The java class looks as below:

package net.codejava.frameworks.spring.bo;
 
public class Title {
      private String titleValue;
 
      public Title(){
      }
     
      public Title(String titleValue){
            this.titleValue = titleValue;
      }
     
      public String getTitleValue() {
            return titleValue;
      }
 
      public void setTitleValue(String titleValue) {
            this.titleValue = titleValue;
      }
}

There are two ways the object of class Title can be instantiated.

1.    Using no-argument constructor followed by setter method

2.    Using constructor with argument

 The java code representation of writing the book title “My First Spring Book”, chapter 1 title “Spring framework - Chapter 1” and chapter2 title “Spring framework - Chapter 2” is shown below:

// Creating the title of the book
// Step 1: Instantiate the object by calling no-argument constructor
Title bookTitle = new Title();
// Step 2: Call the setter method to set title value
bookTitle.setTitleValue("My First Spring Book"); // Setter method
// Creating the titles of the chapters by calling one-argument constructor
Title chapter1Title = new Title("Spring framework - Chapter 1");
Title chapter2Title = new Title("Spring framework - Chapter 2");

Notice that the objects of class Title are depended on titleValue. Without a titleValue, the object of Title class does not have any meaning. Thus titleValue is the dependency for classTitle. When we instantiated the object of class Title with a no argument constructor and then called the setter method to set the value of titleValue, it is known as injecting the dependencies using setter method.  When we instantiated the object of class Title by calling the one-argument constructor, it is known as injecting the dependencies using constructor.

XML based Spring beans configuration

Let us see how these titles will look in a XML based Spring beans configuration file. 

<?xml version="1.0" encoding="UTF-8"?>
<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-3.0.xsd">
 
<!-- Below is an example of injecting the dependencies using setter method -->
<bean id="bookTitle" class="net.codejava.frameworks.spring.bo.Title">
      <property name="titleValue">
            <value>My first Spring book</value>
      </property>
</bean>
<!-- Below are examples of injecting the dependencies using constructor -->
<bean id="chapter1Title" class="net.codejava.frameworks.spring.bo.Title">
      <constructor-arg>
            <value>Spring framework - Chapter 1</value>
      </constructor-arg>
</bean>
<bean id="chapter2Title" class="net.codejava.frameworks.spring.bo.Title">
      <constructor-arg>
            <value>Spring framework - Chapter 2</value>
      </constructor-arg>
</bean>    
</beans>

 

Related Course: The Java Spring Tutorial

 

Annotation based Spring beans configuration

The beans can also be defined in a java class using annotations. Let us assume that the class BeansConfiguration contains the definition of all the Spring beans. Then this class must have a class level annotation Configuration. Each method in this class will represent one bean if it is preceded by a method level annotation Bean. By default the bean name is equal to the method name. However this can be overridden using the name attribute of the Bean annotation. The annotation based representation of Spring bean configuration file is as below. 

@Configuration
public class BeansConfiguration {
      @Bean
      public Title bookTitle(){
            Title title = new Title();
            title .setTitleValue("My first Spring book");
            return title ;
      }
      @Bean
      public Title chapter1Title(){
            returnnew Title("Spring framework - Chapter 1");
      }
       @Bean
      public Title chapter2Title(){
            returnnew Title("Spring framework - Chapter 2");
      }
 
} 

Till now Mr. XYZ has only written the titles (for the book and the two chapters). Now he has started writing the content of the two chapters. Thus we need a java class Chapter. 

package net.codejava.frameworks.spring.bo;
public class Chapter {
      private int number;
      private Title title;
      private String content;
      public Chapter(){
      }
      public Chapter(int number, Title title, String content){
            this.number = number;
            this.title = title;
            this.content = content;
      }
      public int getNumber() {
            return number;
      }
      public void setNumber(int number) {
            this.number = number;
      }
      public Title getTitle() {
            return title;
      }
      public void setTitle(Title title) {
            this.title = title;
      }
      public String getContent() {
            return content;
      }
      public void setContent(String content) {
            this.content = content;
      }
}

Now Mr. XYZ has finished writing the two chapters.  The java code representation is shown below. 

// Injecting the dependencies of chapter1 using setter method
Chapter chapter1 = new Chapter();
Chapter1.setContent("The content of chapter 1 goes here.");
Chapter1.setNumber(1);
Chapter1.setTitle(chapter1Title);
 // Injecting the dependencies of chapter2 using constructor method
Chapter chapter2 =  new Chapter( 2, chapter2Title, "The content of chapter 2 goes here.");

Note that we have already created chapter1Title and chapter2Title. 

Let us see how these chapters will look in an XML based Spring beans configuration file. 

<!-- injecting the dependencies of chapter1 using setter method -->
<bean id="chapter1" class="net.codejava.frameworks.spring.bo.Chapter">
<property name="number">
            <value>1</value>
      </property>
      <property name="content">
            <value>The content of chapter 1 goes here.</value>
      </property>
      <property name="title">
            <ref bean="chapter1Title"/>
      </property>                  
</bean>

Note that while setting the property title in chapter1 bean we have used element ref instead of element value. This is because we have already configured the chapter1Title bean above and are simply referring the bean here.

<!-- injecting the dependencies of chapter 2 using constructor by index -->
<bean id="chapter2" class="net.codejava.frameworks.spring.bo.Chapter">
      <constructor-arg index="0">
            <value>2</value>
      </constructor-arg>     
      <constructor-arg index="1">
            <ref bean="chapter2Title"/>
      </constructor-arg>
      <constructor-arg index="2">
            <value>The content of chapter 2 goes here.</value>
      </constructor-arg>           
</bean>

In the above example of dependency injection using constructor, we have mapped the parameters with constructor arguments by index, explicitly telling which parameter will be mapped with which constructor argument. i.e The value 2 will be mapped with the first constructor argument (index = 0), the chaper2Title will be mapped with seconds constructor argument (index = 1) and value “The content of chapter 2 goes here.” will be mapped with third constructor argument (index = 2).  We can also map the parameters with constructor arguments by their types. The Spring bean representation of chapter2 using dependency injection by constructor by type is shown below.

<!-- injecting the dependencies of chapter 2 using constructor by type -->
<bean id="chapter2" class="net.codejava.frameworks.spring.bo.Chapter">
      <constructor-arg type="int">
            <value>2</value>
      </constructor-arg>     
      <constructor-arg type="net.codejava.frameworks.spring.bo.Title">
            <ref bean="chapter2Title"/>
      </constructor-arg>
      <constructor-arg type="String">
            <value>The content of chapter 2 goes here.</value>
      </constructor-arg>           
</bean>

In case we have not previously defined the bean chapter1Title then we can define it directly while defining the bean chapter1. In this case the bean chapter1Title will be considered as an inner bean. 

<!-- injecting the dependencies of chapter 1 by using inner bean --> 
<bean id="chapter1" class="net.codejava.frameworks.spring.bo.Chapter">
      <property name="number">
            <value>1</value>
      </property>
      <property name="content">
            <value>The content of chapter 1 goes here.</value>
      </property>
      <property name="title">
            <bean class="net.codejava.frameworks.spring.bo.Title">
                  <constructor-arg>
                        <value>Spring framework - Chapter 1</value>
                  </constructor-arg>
            </bean>
      </property>                  
</bean>

The Chapter beans can also be configured in a java class using annotation (as we have configured Title beans) in class BeansConfiguration. 

@Configuration
public class BeansConfiguration {
// Title beans already defined earlier
      @Bean
      public Chapter chapter1(){
            // Injecting the dependencies using setter method
            Chapter chapter = new Chapter();
            chapter.setContent("The content of chapter 1 goes here.");
            chapter.setNumber(1);
            chapter.setTitle(chapter1Title);
            return chapter;
      }
 
      @Bean
      public Chapter chapter2(){
            // Injecting the dependencies of chapter2 using constructor method
            return new Chapter(2, chapter2Title, "The content of chapter 2 goes here.");      }
}

Finally after writing the two chapters, Mr. XYZ decided to compile his book. He has got his book registered with ISBN value of 1 (ignore the ISBM format for this article). The java Book class looks as below.

package net.codejava.frameworks.spring.bo;
import java.util.List;
public class Book {
      private int isbn;
      private String author;
      private Title title;
      private List<Chapter> chapters;
     
      public Book(){
      }
     
      public Book(int isbn, String author, Title title, List<Chapter> chapters){
            this.isbn = isbn;
            this.author = author;
            this.title = title;
            this.chapters = chapters;
      }
     
      public int getIsbn() {
            returnisbn;
      }
      
      public void setIsbn(int isbn) {
            this.isbn = isbn;
      }
      
      public String getAuthor() {
            returnauthor;
      }
      public void setAuthor(String author) {
           this.author = author;
      }
      public Title getTitle() {
            returntitle;
      }
      public void setTitle(Title title) {
            this.title = title;
      }
      public List<Chapter> getChapters() {
            return chapters;
      }
      public void setChapters(List<Chapter> chapters) {
            this.chapters = chapters;
      }
}

Below is Mr. XYZ’s firstSpringBook bean in XML based Spring configuration file.

<bean id="myFirstSpringBook" class="net.codejava.frameworks.spring.bo.Book">
      <property name="isbn">
            <value>1</value>
      </property>
      <property name="author">
            <value>Mr. XYZ</value>
      </property>
      <property name="title">
            <ref bean="bookTitle"/>
      </property>
      <property name="chapters">
            <list>
                  <ref bean="chapter1"/>
                  <ref bean="chapter2"/>
            </list>
      </property>
</bean>    

Note that in the above bean definition we have made references to previously defined bookTitle bean and chapter1 & chapter2 beans. Also we have used setter based dependencies injection. 

Annotation based bean definition of myFirstSpringBook bean is as below:

@Configuration
public class BeansConfiguration {
 
// Title and Chapter beans already defined earlier
     
      @Bean
      public Book myFirstSpringBook(){
            Book book = new Book();
            book.setIsbn(1);
            book.setAuthor("Mr. XYZ");
            book.setTitle(bookTitle);
            List<Chapter> chapters = new ArrayList<Chapter>();
            chapters.add(chapter1);
            chapters.add(chapter2);
            book.setChapters(chapters );
            return book;
      }
}

Finally Mr. XYZ has published his book on Spring framework. And he is now ready to write many more books on his favourite topics. 

Let us recap what we have learned so far.

1.       Spring beans definition in

a.       XML based Spring definition file

b.      Java annotation based Spring definition file

2.       Dependencies injection

a.       Using setter method

b.      Using constructor

 i.Mapping via index

 ii.Mapping via Type

3.       Inner beans

4.       Referring previously defined beans

Recommended Book: Spring in Action

Attachments:
Download this file (MyFirstSpringProject.zip)MyFirstSpringProject.zip[Java project in Eclipse IDE]2197 kB
Start learning on Udemy today!