Spring Boot

 

 Spring Boot

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".

Features of Spring boot

  • Create stand-alone Spring applications

  • Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)

  • Provide opinionated 'starter' dependencies to simplify your build configuration

  • Automatically configure Spring and 3rd party libraries whenever possible

  • Provide production-ready features such as metrics, health checks and externalized configuration

  • Absolutely no code generation and no requirement for XML configuration

Developing Spring Application before Spring Boot

Using Spring Initializr to create Spring Boot Project

 

  • Go to https://start.spring.io/
  • With the help of option on the page create a gradle project with latest version of Spring Boot
  • Download the project and import it in idea
  • Once you import the project in Intellij Idea then try running the application by executing the Main Class

 

(Note : Please see the next slide to get know all the options you want to select)

Create a simple Rest Controller

package com.springbootdemo.basics.entity;

public class Book {

    private Integer id;
    private String name;
    private String author;

    public Book(Integer id, String name, String author) {
        this.id = id;
        this.name = name;
        this.author = author;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }
}
package com.springbootdemo.basics.service;

import com.springbootdemo.basics.entity.Book;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;

@Service
public class BookService {

    public List<Book> getBooks(){
        return Arrays.asList(new Book(1,"Book1","Author1"),
                new Book(2,"Book2","Author2"));
    }
}
package com.springbootdemo.basics.controller;

import com.springbootdemo.basics.entity.Book;
import com.springbootdemo.basics.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class BookController {

    @Autowired
    BookService bookService;


    @GetMapping("/books")
    public List<Book> getBooks(){
        return bookService.getBooks();
    }
}

Difference between @RestController and @Controller

@SpringBootApplication

@SpringBootApplication indicates following things :

  • Its a Spring Context File
  • It performs component scan to register the spring bean

Configuring a Bean with Component Scan

package com.springbootdemo.basics.entity;

public interface HotDrink {

    void prepareDrink();
}
package com.springbootdemo.basics.entity;

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

@Component
public class Restaurant {

    @Autowired
    private HotDrink hotDrink;


    public HotDrink getHotDrink() {
        return hotDrink;
    }

    public void setHotDrink(HotDrink hotDrink) {
        this.hotDrink = hotDrink;
    }
}
package com.springbootdemo.basics.controller;

import com.springbootdemo.basics.entity.Restaurant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RestaurantController {

    @Autowired
    Restaurant restaurant;

    @GetMapping("/prepareDrink")
    public String prepareDrink(){
        restaurant.getHotDrink().prepareDrink();
        return "Drink is Ready";
    }

}

Creating the bean in context file

package com.springbootdemo.basics.entity;

public class Restaurant {

    private HotDrink hotDrink;


    public HotDrink getHotDrink() {
        return hotDrink;
    }

    public void setHotDrink(HotDrink hotDrink) {
        this.hotDrink = hotDrink;
    }
}
package com.springbootdemo.basics;

import com.springbootdemo.basics.entity.HotDrink;
import com.springbootdemo.basics.entity.Restaurant;
import com.springbootdemo.basics.entity.Tea;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class BasicsApplication {

	@Bean
	public Restaurant restaurant(HotDrink hotDrink){
		Restaurant restaurant= new Restaurant();
		restaurant.setHotDrink(hotDrink);
		return restaurant;
	}

	@Bean
	Tea tea(){
		return new Tea();
	}
	
	public static void main(String[] args) {

	 SpringApplication.run(BasicsApplication.class, args);
	}
}

application.properties

  • We can place certain common properties which will be used at many places in a common place known as application.properties
app.name=My basic app
  • Following is the way to retrieve the value from the properties file:
package com.springbootdemo.basics.controller;

import com.springbootdemo.basics.entity.Restaurant;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RestaurantController {

    @Autowired
    Restaurant restaurant;

    @Value("${app.name}")
    String appName;

    @GetMapping("/prepareDrink")
    public String prepareDrink(){
        System.out.println("App Name is : "+appName);
        restaurant.getHotDrink().prepareDrink();
        return "Drink is Ready";
    }

}
  • profile-specific properties can also be defined by using the following naming convention: application-{profile}.properties
  • We can also specify some app specific configurations which will be automatically picked by spring boot e.g

 

server.port=8081

After setting the value above if you try to run application then it will run on port 8081

Different ways of running a Spring Boot App

  • Run the Main java class marked with @SpringBootApplication Annotation and contains main method as follows:
        public static void main(String[] args) {

	     SpringApplication.run(BasicsApplication.class, args);
	}
  • Execute the bootRun Gradle tasks
  • Create an Executable jar with the help of bootJar Gradle task. This task will build an executable jar inside build/libs folder. Now execute the jar files using command below:
java -jar basics-0.0.1-SNAPSHOT.jar 
java -jar basics-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod
java -jar basics-0.0.1-SNAPSHOT.jar --server.port=8080

Logging Levels

Level Description
TRACE Designates finer-grained informational events than the DEBUG.
DEBUG Designates fine-grained informational events that are most useful to debug an application.
INFO Designates informational messages that highlight the progress of the application at coarse-grained level.
WARN Designates potentially harmful situations.
ERROR Designates error events that might still allow the application to continue running.

Setting the log level in Spring Boot

We can set the log level in spring boot my mentioning the log level in application.properties as follows:

 

logging.level.root=TRACE
logging.level.com.springbootdemo.basics.controller=INFO
package com.springbootdemo.basics.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LoggingController {

    Logger logger = LoggerFactory.getLogger(LoggingController.class);

    @RequestMapping("/logging")
    public String index() {
        logger.trace("A TRACE Message");
        logger.debug("A DEBUG Message");
        logger.info("An INFO Message");
        logger.warn("A WARN Message");
        logger.error("An ERROR Message");

        return "Logs Printed....";
    }
}

Perform some operation when application starts

package com.springbootdemo.basics.event;

import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

@Component
public class Bootstrap {

    @EventListener(ApplicationStartedEvent.class)
    public void init(){
        System.out.println("Your Application is up and running");
    }
}

Configure Spring Data JPA

application.properties

spring.datasource.url=jdbc:mysql://localhost/rest_with_spring
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.ddl-auto=create
package com.springbootdemo.basics.entity;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
public class Book {

    @Id
    private Integer id;
    private String name;
    private String author;

    public Book(Integer id, String name, String author) {
        this.id = id;
        this.name = name;
        this.author = author;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }
}

Convert Book Class in to hibernate entity

CrudRepository for Book

package com.springbootdemo.basics.repository;

import com.springbootdemo.basics.entity.Book;
import org.springframework.data.repository.CrudRepository;

public interface BookRepository extends CrudRepository<Book, Integer> {
}
package com.springbootdemo.basics;

import com.springbootdemo.basics.entity.HotDrink;
import com.springbootdemo.basics.entity.Restaurant;
import com.springbootdemo.basics.entity.Tea;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@SpringBootApplication
@EntityScan(basePackages = {"com.springbootdemo.basics.entity"})
@EnableJpaRepositories(basePackages = {"com.springbootdemo.basics.repository"})
public class BasicsApplication {

    @Bean
    public Restaurant restaurant(HotDrink hotDrink) {
        Restaurant restaurant = new Restaurant();
        restaurant.setHotDrink(hotDrink);
        return restaurant;
    }

    @Bean
    Tea tea() {
        return new Tea();
    }

    public static void main(String[] args) {

        SpringApplication.run(BasicsApplication.class, args);
    }
}

Enabling JPA Repository

Bootstraping Initial data

package com.springbootdemo.basics.event;

import com.springbootdemo.basics.entity.Book;
import com.springbootdemo.basics.repository.BookRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

import java.util.Iterator;

@Component
public class Bootstrap {


    @Autowired
    BookRepository bookRepository;

    @EventListener(ApplicationStartedEvent.class)
    public void init() {
        Iterator<Book> bookIterable = bookRepository.findAll().iterator();
        if (!bookIterable.hasNext()) {
            for (int i = 1; i <= 10; i++) {
                Book book = new Book(i, "Book " + i, "Author " + i);
                bookRepository.save(book);
                System.out.println("Book " + i + " created");
            }
        }
        System.out.println("Your Application is up and running");
    }
}

Getting the books from database

package com.springbootdemo.basics.service;

import com.springbootdemo.basics.entity.Book;
import com.springbootdemo.basics.repository.BookRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@Service
public class BookService {

    @Autowired
    BookRepository bookRepository;

    public List<Book> getBooks(){
        List<Book> bookList = new ArrayList<>();
        Iterator<Book> bookIterator = bookRepository.findAll().iterator();
        bookIterator.forEachRemaining(bookList::add);
        return bookList;
    }
}

Spring Boot

By Pulkit Pushkarna

Spring Boot

  • 1,735