Home Spring Spring Core Spring Core | Bean & Wiring | Part-1

Spring Core | Bean & Wiring | Part-1

Just imagine your favorite dish, it takes how many ingredients to pull together a dish which waters your mouth. These ingredients compliment or just say work in collaboration with each other to develop that exquisite taste. Now imagine what your favorite dish would be like had one of the ingredients is missing or added inappropriately.

In this respect, a great piece of software isn’t much different. Any non-trivial Java application is made up of several objects that must work together to meet some business goals. These objects must be aware of one another and communicate with one another to get their jobs done. These object which we are talking about, act as a backbone of our application is called Bean or JavaBeans in Spring lingo. We will be referring these objects as spring beans in future posts interchangeably.

In our previous post, we learned that beans shouldn’t be responsible for finding or creating other dependent beans to do their jobs. Instead, the container should give them a reference to their dependency. We also learned that the act of creating this association is called wiring.

Spring Configuration

As mentioned earlier, the Spring container is responsible for creating and managing relationships between beans via DI. But it’s your responsibility to tell spring container which beans to create and how to wire them. There are different ways to do that:

  • Automatic bean discovery and wiring
  • Explicit configuration in XMLs
  • Explicit configuration in Java

I’d favor the type-safe and more powerful JavaConfig over XML but it’s more of a personal choice. You can also mix JavaConfig and XML based upon your use-case.

Automatic Bean Discovery and Wiring

Spring can configure automatic wiring by two angles:

  • Component Scanning: Spring automatically discovers beans to be created in the application context.
  • Autowiring: Spring automatically discovers beans and satisfies dependencies.

To demonstrate the above two concepts we will be creating a few beans and wire them together.

Creating Discoverable Beans

In our previous post, we saw how Class Student should be injected with Interface Subject in order to function.

public Interface Subject
{
  public void attend();
}

import org.springframework.stereotype.Component;

@Component
public class History implements Subject
{
  private String content = "history chapter";
  @Override
  public void attend(){
    System.out.print("Reading :" + content);
  }
}

The important thing to note above is that we have defined Subject as an Interface so that it can keep coupling between the implementation of Subject and the Student itself minimum. What you should also take note that we have annotated class History with @Component. This annotation identifies this class as a component class and serves as a clue to Spring that a bean should be created for this class.

However, Component scanning isn’t turned on by default. You’ll write an explicit configuration to tell Spring to check if our classes are annotated with @Component and create beans for them. Let us see how to write such a configuration.

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages="com.lifeinhurry")
public class StudentConfig{
}

Class StudentConfig defines a Spring wiring specification, expressed in Java. We’ll learn more about Java-based spring configuration in further posts. But for now, observe that StudentConfig doesn’t explicitly define any beans itself. Instead, it’s annotated with @ComponentScan to enable component scanning in Spring. This will enable Spring to scan all components in com.lifeinhurry package and it’s sub-packages (You can also configure multiple packages in ComponentScan). Spring will find class History with @Component annotation and will automatically create a bean in a Spring container.

Let us see if component scanning really works or not with the help of Junit test, that will create a Spring application context and test if Subject bean is actually created or not.

import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=StudentConfig.class)
public class StudentTest
{
  @Autowired
  private Subject subject;

  @Test
  public void subjectShouldNotBeNull() {
    assertNotNull(subject);
  }
}

StudentTest takes advantage of spring’s SpringJUnit4ClassRunner to have a spring application context automatically created when the test starts. And the @ContextConfiguration annotation tells it, to load configuration from the class StudentConfig. Because that configuration class includes ComponentScan, the resulting application context should include the Subject bean.

We learned how we can create a standalone bean in the Spring application context. But we know, many objects lean on other objects to get the job done. We need a way to wire our component-scanned beans with any dependency they have. To do that, we will look at autowiring further.

Annotating Beans for Autowiring

Spring automatically let beans to find their dependency within the application context, it is called autowiring. For autowiring to be enabled we need to use @Autowired annotation. To illustrate this, we will look at class Student, how it can be wired with bean of type Subject.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Student implements Person
{
  private Subject subject;
  @Autowired
  public Student (Subject subject) {
    this.subject= subject;
  }

  public void attendSubject() {
    subject.attend();
  }

Spring has already created a Subject bean in its container using @ComponetScan feature which we saw earlier. In the above example, Spring passes the bean to class Student via the constructor. Since the constructor is annotated with @Autowired it let Spring know that it has a dependency on a bean of type Subject to perform its job. It becomes the responsibility of Spring to find and satisfies Student dependency.

The @Autowired annotation’s use isn’t limited to constructors. It can be used in multiple ways:

//Option1: Can be used with setters
@Autowired
public void setSubject(Subject subject) {
  this.subject= subject;
}
//Option2: Can be used with any method
@Autowired
public void assignSubject(Subject subject) {
  this.subject= subject;
}
//Option3: Can be used directly with variable
@Autowired
private Subject subject;

Now, we can be assured that the Spring will automatically inject Student with its dependency. To be more certain, let us verify it by modifying StudentTest to attend class through Student bean.

import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=StudentConfig.class)
public class StudentTest
{
  @Autowired
  private Subject subject;

  @Rule
  public final StandardOutputStreamLog log = new StandardOutputStreamLog();
  
  @Autowired
  private Student student;

  @Test
  public void subjectShouldNotBeNull()
  {
    assertNotNull(subject);
  }

  @Test
  public void testAttendSubject()
  {
    assertEquals("Reading :history chapter", log.getlog());
  }
}

Now we know the basics of component scanning and autowiring. We learned how Spring can be configured to automatically create, identify, and manage beans and their dependency. Sometimes, the automatic bean wiring may not be sufficient and we may have to write some explicit configuration. We will learn how to do that in our next post.

lifeinhurryhttp://lifeinhurry.com
lifeinhurry.com is a digital platform to explain about various topics on finance, career, programming and lifestyle and writes in hope and passion that one person will be better because he or she reads what we wrote.

1 COMMENT

  1. Great Content. Really helpful with proper examples which helped me in understanding the concepts with clarity. Is there any way by which I can subscribe to this?

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Spring Bean Scope

What is the Spring Bean Scope? The Spring Framework is responsible for creating and managing beans in its container. It is also...

Resolve Ambiguity in Spring Beans

So far in this series, we have learned how we can leverage auto-configuration to enable Spring to create beans and wire them...

Spring Core | Bean & Wiring | Part-2

In our previous post, we learned how we can create beans automatically by using @Component and wire them with other objects using...

Spring Core | Bean & Wiring | Part-1

Just imagine your favorite dish, it takes how many ingredients to pull together a dish which waters your mouth. These ingredients compliment...