Spring Boot HandBook

    Introduction#

    Spring Boot revolutionizes the way Spring applications are developed by reducing the configuration burden. A key feature enabling this is Auto Configuration, which automatically sets up your application based on the dependencies present on the classpath.

    Things to understand before understanding Auto Configuration#

    pom.xml or build.gradle#

    Maven is a popular build automation tool used in many java projects. In a Spring Boot project, dependencies are specified in the pom.xml file. Maven then resolves these dependencies and includes them in the classpath

    Same thing is done by build.gradle in gradle project Note:- Class-path is like a parameter to a JVM to look for user-defined classes and packages in java program when you compile or run a Java program

    Spring Boot Starters#

    Starters like spring-boot-starter-parent include a ton of third-party libraries into your project - by default. Its AutoConfigurations use these dependencie to setup and preconfigure these libraries automatically.

    For Example :

    When we addspring-boot-starter-web dependency to pom.xml then it also includes dependencies like Spring MVC, embedded Tomcat server, Jackson, and more.

    Including a starter automatically registers these dependencies in your application’s classpath, which is a key factor in enabling Spring Boot's Auto Configuration.

    spring-boot-dependencies pom.xml#

    The spring-boot-dependencies pom.xml contains every 3rd party library and version that Spring boot knows. These libraries are predefined in a dependencyManagement section, so you do not need to specify the version numbers in your own project, anymore.

    What is Auto Configuration?#

    Autoconfiguration refers to the mechanism that automatically configures Spring applications based on the dependencies present on the classpath and other application-specific settings.

    This feature simplifies the setup and development process, allowing developers to focus more on writing business logic rather than configuring the framework.

    How Auto Configuration Works#

    When we add spring-boot-starter-web dependency in pom.xml file and started our application, as our application starts the embedded tomcat server also starts on default port 8080, here we have not set anything like on which port it should listen but by default it is listening on 8080 port.

    This happened by default because everything related to spring-boot web was Auto configured by AutoConfiguration and we did not defined anything.

    The AutoConfiguration file related to Spring-boot-starter-web dependency is responsible for the things that are auto configured related to web it has all the defaults.

    Auto Configuration files location#

    All Auto-configuration logic is implemented in spring-boot-autoconfigure.jar which is present in external libraries.

    In detail flow of how Auto configuration work#

    1. Classpath Scanning#

    Spring boot scans the classpath for the presence of certain libraries and classes. Based on what it finds, it applies corresponding configurations.

    Spring boot application will look for one annotation and i.e. @SpringBootApplication

    The @SpringBootApplication wraps @EnableAutoConfiguration annotation with in it due to which auto-configuration feature is enabled in our application.

    The @SpringBootApplication also wraps @ComponentScan annotation with in it which scans for all the different annotations defined inside the different files under the base-package like @Service, @RestController, @Repository and registers them as bean.

    There are multiple ways of scanning one of this was annotation based scanning there is another pom.xml based scanning, the classpath scanning will look for dependencies in pom.xml and see that the particular dependency have been added to the classpath and load the auto configuration related to that dependency.

    2. Configuration Classes#

    Spring boot contains numerous autoconfiguration classes, each responsible for configuring a specific part of the application.

    The configuration classes related to dependencies get loaded as the dependencies are added to classpath

    3. Conditional Beans#

    Each autoconfiguration class uses conditional checks to decide if it should be applied. These conditions include the presence of specific classes, the absence of user-defined beans, and specific property settings.

    For example let us consider HibernateJpaAutoConfiguration class#

    1. @AutoConfiguration#

    • Purpose: The @AutoConfiguration annotation is used to define the order in which this configuration class should be applied in relation to other configuration classes.
    • Attributes:
      • after = {DataSourceAutoConfiguration.class, TransactionManagerCustomizationAutoConfiguration.class}: Specifies that this configuration should be applied after DataSourceAutoConfiguration and TransactionManagerCustomizationAutoConfiguration. This ensures that the data source and any transaction manager customizations are set up before the JPA (Java Persistence API) configuration.
      • before = {TransactionAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class}: Specifies that this configuration should be applied before TransactionAutoConfiguration and DataSourceTransactionManagerAutoConfiguration. This ensures that JPA-related configurations are established before the general transaction management configurations are applied.

    2. @ConditionalOnClass#

    Purpose: The @ConditionalOnClass annotation is used to ensure that this configuration is only applied if certain classes are present on the classpath.

    Attributes:

    • {LocalContainerEntityManagerFactoryBean.class, EntityManager.class, SessionImplementor.class}: This configuration will only be applied if these classes are present on the classpath.
      • LocalContainerEntityManagerFactoryBean: A Spring class that helps manage an EntityManagerFactory for JPA.
      • EntityManager: The JPA interface used for interacting with the persistence context.
      • SessionImplementor: An interface from Hibernate that provides session-related functionality.

    3. @EnableConfigurationProperties#

    • Purpose: This annotation is used to bind properties from external configuration sources (like application.properties or application.yml) to a specific configuration class.
    • Attributes:
      • {JpaProperties.class}: This tells Spring Boot to bind any properties prefixed with spring.jpa (as defined in the JpaProperties class) to an instance of JpaProperties. This class would typically contain properties like spring.jpa.show-sql, spring.jpa.hibernate.ddl-auto, etc.

    4. @Import#

    • Purpose: The @Import annotation is used to import additional configuration classes into the current configuration.
    • Attributes:
      • {HibernateJpaConfiguration.class}: This imports the HibernateJpaConfiguration class, which contains additional configuration necessary for setting up Hibernate as the JPA provider.

    Spring boot Internal Flow#

    1. Initialization#

    When you start a Spring Boot application, the main entry point is typically a class annotated with @SpringBootApplication (or its meta-annotations). This annotation combines several other annotations such as @Configuration, @EnableAutoConfiguration, and @ComponentScan.

    2. Spring Application Context Creation#

    Spring Boot creates an application context, which serves as the container for managing beans and their dependencies. It scans the classpath for components, configurations, and auto-configurations, and initializes the application context based on the detected classes and dependencies.

    3. Auto Configuration#

    Spring Boot auto-configures beans and components based on the classpath and detected dependencies. It uses conditional annotations (@ConditionalOnClass, @ConditionalOnBean, etc.) to conditionally configure beans only if certain conditions are met.

    4. Externalized Configuration#

    Spring Boot loads configuration properties from various sources, such as property files, YAML files, environment variables, and command-line arguments. It provides sensible default values for configuration properties and allows them to be easily overridden or customized.

    5. Embedded Web Server Initialization#

    If the application is a web application, Spring Boot initializes the embedded web server (such as Tomcat, Jetty, or Undertow) based on the application's dependencies and configurations. It configures the server with sensible defaults and starts it to listen for incoming requests.

    6. Application Startup#

    Spring Boot invokes lifecycle callbacks such as @PostConstruct methods and initialization callbacks on beans as the application context is being initialized. Beans are instantiated, dependencies are injected, and any necessary initialization logic is executed.

    7. Application Ready#

    Once the initialization process is complete, the application context is fully initialized and ready to handle requests. The embedded web server is up and running, and the application is ready to serve incoming HTTP requests.

    In this article, we delved into the concept of Auto Configuration in Spring Boot, examining how it simplifies the development process by automatically setting up applications based on the dependencies present on the classpath. We discussed the importance of build files like pom.xml and build.gradle, the role of Spring Boot Starters in managing dependencies, and how the spring-boot-dependencies POM simplifies version management. Furthermore, we explored the mechanics of Auto Configuration, including classpath scanning, the role of configuration classes, and the use of conditional annotations to manage bean creation. Finally, we outlined the internal flow of Spring Boot applications from initialization to being ready to handle requests, illustrating how Auto Configuration contributes to a streamlined and efficient development experience.

    Last updated on Oct 13, 2024