# Spring Boot

## Problems with traditional Spring Application

* We use different modules from spring such as,
  * Core module, to do dependency injection.
  * The MVC module to develop the web layer for our application or even the restful web services layer.
  * The DAO layer where we use the spring `JDBC/ORM` which makes our life easy to develop a data access layer for our application.
  * While using ORM tools like Hibernate, we can use spring data JPA and we use these modules and more, that are valuable from Spring.
* Configuration
  * We used XML based configuration or annotations based configuration. This configuration can get difficult and hard to maintain over time.
  * And also we need to make sure that each of these modules is available for our application by defining all the dependencies in the Maven POM.
  * And at runtime we have to be sure that these versions of various Modules that we use are compatible with each other.
  * It's our responsibility to do all that, and once we have all that in place we will build our application and will have to deploy the application to an external web container to test it.
* A brief history of Spring framework evolution can be found [here](https://www.quora.com/What-is-the-history-of-The-Spring-Framework).

## Spring boot

* This [ticket](https://github.com/spring-projects/spring-framework/issues/14521) raised for creating Spring Boot, which changed how spring applications are developed.
* What is Spring Boot?
  * Spring Boot is a Framework from "The Spring Team" to ease the bootstrapping and development of new Spring applications.
  * Spring Boot is a production ready spring project with embedded web server and configuration files.
  * It provides defaults for code and annotation configuration to quick start new Spring projects within no time. Spring projects required quite a bit of configuration. Some of this configurations are boilerplate code related to persistence, file upload etc. It has nothing to do with business requirements.
  * Spring Boot is a framework that will set up much of this configuration automatically, helping you get your project up and running as quickly as possible.
  * It follows **Opinionated Defaults Configuration** approach to avoid lot of boilerplate code and configuration to improve Development, Unit Test and Integration Test Process.
* What are Spring Boot Features?
  1. **Auto configuration** : Spring Boot automatically configures everything that is required for our application. We don't have to use `XML` or annotation based or Java configuration anymore.
     * For example, if you are using Spring MVC or the web to develop a web application or a restful web service application spring boot will automatically configure the dispatcher servlet and does all the request mapping for us. We don't have to use any xml or annotation based configuration to configure dispatcher servlet.
     * Similarly, if you are using spring data for object relational mapping while working with tools like Hibernate to perform database CRUD operations, we no longer have to configure the data source or even the transaction manager. Spring boot will automatically configure these for our application.
  2. **Spring boot starters** : With the spring boot starters spring boot solved the problem of module availability we need. Before Spring Boot we had to make sure that a particular library required for our project is available and also the versions of different libraries are compatible. But we don't have to do that anymore, thanks to spring boot starters. Every spring boot project will have a parent project. This project has all the version information of various libraries that we will be using in our project so we need not worry about version compatibility. The spring developers have already done it for us and put all that information into this spring boot starter parent.
     * Secondly, we have starters for different types of projects. If we are developing a web project then we simply need to include the _starter web_ dependency. We don't have to include any other libraries or dependencies. Maven _(or any dependency management tool)_ will automatically pull those libraries. The spring boot developers have given us starter dependencies which when we use in our projects will not have the modular availability problem and the version compatibility problem.
     * Another example is, the **spring boot starter data jpa**. When you want to work with `Hibernate` you simply include the single dependency in your maven `pom.xml` and all the other libraries will be pulled accordingly. And also the correct versions of those libraries will be included because all that version information is available in this spring boot starter parent which is a parent for every spring boot project.
  3. **Embedded servlet container**: Deploying our applications to external container becomes easy as spring boot comes with an embedded servlet container.
     * By default, it is Tomcat but you can also use `Jetty` and `Undertow` or any other external server. So, no longer you have to worry about external deployment. You can simply right click on your project and run it and your application will be launched on its embedded Tomcat server by default.
  4. **Health checks** : `Spring Boot Actuators` enable easy health checks for our application. We can use different types of health checks that come for free and we can use these even on production when our application is running. These can be activated easily and will display all the auto configuration reports and everything that is automatically configured for our application.

## Important Annotations of a Spring Boot Application

*   Entry point

    ```java
        @SpringBootApplication
        public class HellospringbootApplication { 

            public static void main(String[] args) {
                SpringApplication.run(HelloSpringBootApplication.class, args);
            }
        }
    ```

    * `org.springframework.boot.SpringApplication` class is used to bootstrap and launch a Spring application from a Java main method.
    * By default, this class will perform the following steps to bootstrap the application,
      1. Create an ApplicationContext instance _(representing Spring Container)_.
      2. Manages life-cycle of spring beans.
    * `@SpringBootApplication`
      * This annotation is where all the spring boot magic happens.
      * It is a key annotation which is a top level annotation which contains several other annotations on it such as,
        * `org.springframework.boot.@SpringBootConfiguration` : Tells spring boot or the container that this class here can have several bean definitions. We can define various spring beans here and those beans will be available at run time if you define a method with `@Bean` annotation here.
        * `org.springframework.boot.autoconfigure.@EnableAutoConfiguration` : It is a very important annotation that enable Auto configuration. This annotation tells spring boot to automatically configure the spring application based on the dependencies that it sees on the classpath.
          * For example, if you have a MySql dependency in your `pom.xml`, then Spring Boot will automatically create a data source. You will also provide other information like username, password etc. but spring boot will scan through all these dependencies and it will automatically configure the data source required for you.
          * Another example is spring web, if you have spring web in your dependencies. Then spring boot will automatically create the dispatcher servlet.
          * All the xml, all the java based configuration is now gone. Developers need not do all that configuration, as all that comes for free thanks to spring boot because of its `@EnableAutoConfiguration` annotation.
        * `org.springframework.context.annotation.@ComponentScan` : This tells that spring boot or spring should scan through the classes and see which all classes are marked with the stereotype annotations like `@Component`, `@Controller`, `@Service`, `@Repository` and manage these spring beans .
          *   **Note**: Default base package is the package in which `Main` class is defined. However, this can be overridden by providing annotation property `basePackages`.

              * eg

              ```java
                  @ComponentScan(basePackages = "com")
              ```
          * This annotation is equivalent to xml tag `<context:component-scan>`.
    *   For scanning entities use `@EntityScan`.

        * This annotation is used to scan entity classes, which are in a different root package hierarchy than `Main` class.

        ```java
            @EntityScan(basePackages = "com.app.pojos")
        ```

        * Using this annotation will disable the auto configuration capability of `@EnableAutoConfiguration` for entity classes.

## Advantages of Spring Boot

* It makes development of Spring Based applications with Java very easy.
* It reduces lots of development time and increases productivity.
* It reduces writing lots of boilerplate Code, Annotations and XML Configuration.
* It is very easy to integrate Spring Boot Application with its Spring Ecosystem like Spring JDBC, Spring ORM, Spring Data, Spring Security etc.
* It follows “Opinionated Defaults Configuration” Approach to reduce Developer effort.
* It provides Embedded HTTP servers like Tomcat, Jetty etc. to develop and test our web applications very easily.
* It provides CLI _(Command Line Interface)_ tool to develop and test Spring Boot _(Java or Groovy)_ Applications from command prompt very easily and quickly.
* It provides lots of plugins to develop and test Spring Boot Applications very easily using Build Tools like _Maven_ and _Gradle_.
* It provides lots of plugins to work with embedded and in-memory Databases _(like H2 database)_ very easily.

## What is "Opinionated Defaults Configuration"

* When we use Hibernate/JPA, we would need to configure a datasource, a session factory, a transaction manager among lot of other things.
* Spring Boot looks at it differently.
  * By auto-configuring a datasource i.e., connection pool/session factory/Transaction manager, if `Hibernate` jar is on the classpath.
  * When a spring mvc jar is added into an application, spring auto configure some beans automatically such as _HandlerMapping_, _ViewResolver_ and configure _DispatcherServlet_.
* Spring, of course allow and provision ways to override the default auto configuration.

## How does @EnableAutoConfiguration work?

* Spring Boot looks at `jars` available on the `CLASSPATH` and existing configuration for the application.
* Based on these, Spring Boot provides basic configuration needed to configure the application with these frameworks. This is called **Auto Configuration**.

## What is Spring Boot Starter?

* Starters are a set of convenient dependency descriptors that you can include in your application's `pom.xml`.
* For example, suppose you want to develop a web application, without Spring boot, you would need to identify the frameworks we want to use, which versions of frameworks to use and how to connect them together.
* But all web application have similar needs.
  * These include Spring MVC, Jackson Databind (for data binding), Hibernate-Validator _(for server side validation using Java Validation API)_ and Log4j _(for logging)_.
  * Earlier while creating any web app, we had to choose the compatible versions of all these frameworks.
*   With Spring boot, You just add Spring Boot Starter Web.

    ```maven
        //Dependency for Spring Boot Starter Web
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    ```
* Just by adding above starter, it will add necessary and compatible JARs under maven dependencies.
* Another example, if you want to use Spring and JPA for database access, just include the `spring-boot-starter-data-jpa` dependency in your project, and you are good to go.
