Spring Boot Auto-configuration and Project Structure

In this tutorial, we will look at the auto-configuration and the structure of our web project in detail. It is necessary to follow the coding conventions such as using a named package instead of a default package. These packages will be scanned by spring-boot to identify the beans and entities defined in your project. Below is the directory structure along with the Java class files that we will be creating.

Importance of the Root Package

  • To launch the application, we will be running the class with main method (usually placed in the root package) and it is annotated with @SpringBootApplication.

  • @SpringBootApplication annotation is responsible for bootstrapping the application.

  • If we compare the above project structure, Application.java is the file which is annotated with @SpringBootApplication and is in the package com.studytonight.tutorial (root package).

  • Entities like Student and Teacher are scanned by spring-boot because their package is inside root package and as follows.

    • Application.java (com.tutorial.studytonight)

    • Student.java (com.tutorial.studytonight.pojo)

    • Teacher.java (com.tutorial.studytonight.pojo)

We can observe that com.tutorial.studytonight is common for Student.java and Teacher.java classes. Any component placed under the root package will be scanned automatically by spring-boot.

What is Auto-Configuration?

It is enabled after scanning the classpath. Annotations such as @EnableAutoConfiguration is responsible for auto-configuring. For example, when the project is provided with dependencies such as spring-boot-starter-data-jpa, spring-boot expects the database details such as username, password, url without which the application fails to launch as the spring-boot scans the spring-boot-starter-data-jpa dependencies in classpath and assumes that the project will be using a database. Remember, we have added the H2 dependency in the project setup (spring boot auto-configures the database properties for H2).

In some cases, to test the application, we prefer to use an in-memory database before final deployment in the production with a relational database.

What are Beans?

  1. These are the objects that form the backbone of the spring application. Some beans are created by spring itself at the time of launch, based on auto-configuration.

  2. A programmer may also define his/her own beans using the annotation @Bean which will be discussed further.

  3. These beans may be used for autowiring when required. Autowiring is nothing but injecting the beans into other java class files which is done by spring itself.

For example, every Student is associated with a Teacher and in the below classes, we are instantiating the class Teacher in the class Student which is an example of tight coupling.

class Teacher {

   private String name;
   private String subject;

   //setter and getter methods

}

class Student {

   private String name;
   private int age;
   private Teacher teacher = new Teacher();

   //setter and getter methods

}

To autowire the Teacher bean, we need to create a bean of Teacher class (which will be managed by spring).

@Configuration
class BeanList{

    @Bean
    public Teacher teacherBean(){
         Teacher teacher = new Teacher();
         return teacher;
    }
}

The above class is annotated with @Configuration so that the spring boot looks for any configuration inside the class. The bean created will be managed by spring and it is injected when autowiring is required in Student class.

class Student {

    private String name;
    private int age;

    @Autowired
    private Teacher teacher;   //Instance will be autowired by spring

}

Conditional Auto-Configuration:

In some cases, we can restrict the auto-configuration by using annotations. Let us assume that, we need to create a bean of Student but we need to create the bean of Teacher class first, so, create the Student bean if Teacher bean is available. Let us implement this using annotations.

@Bean
@ConditionalOnBean(Teacher.class)
public Student studentBean() {
    Student student = new Student();
    return student;
}

The above code snippet creates the studentBean only when the teacherBean is available. Similarly, @ConditionalOnMissingBean can be used to create a bean when one bean is missing.

Conclusion: In this tutorial, we have seen the project layout and auto-configuration feature available in spring-boot.