Spring Boot

Introduction
  • The developer of Spring Boot tweeted a web service made up of  140 characters which could run as a fully functional project.
  • Spring Boot is based on groovy.
  • To run a basic mvn managed Spring Boot Application just create a basic application from start.spring.io.
    • Add index.html file to src/main/resources/static
    • Compile using "mvn clean package"
      • You will get jar in target folder.
    • Run the jar using java -jar jarfile
    • Your application will run on port 8080 by default.
  • Spring Boot is a way in which we can quickly bootstrap or startup a Spring application
    • Spring Boot makes it easy to create standalone, production-grade Spring based applications that you can "just run".
  • Spring Boot is opinionated i.e. it makes certain starting decisions for you where from you can start off.
    • If required then we may make changes this is a concept of convention over configuration.
  • Spring Boot Application runs out of the box we do not need to deploy it to a tomcat container or some other container.
    • We do not require a servlet container to deploy it too.
  • Spring Boot is production ready i.e. we have to do nothing to deploy it to production.
  • Spring is an application framework.
    • It has a programming and configuration model.
      • We focus only on building our business services.
    • Concerns like connecting to database,running queries,handling Http request,Having an MVC layer are automatically handled by Spring. 
    • There are POJO classes and we have annotations on them which denote what they are.
    • If we write our Business Service we write it with code specific to our business logic.
      • We annotate this class with @Service and Spring knows that this class is a service.
      • This applies whole lot of things to the lifecycle of the class thus it acts as a service.
    • Spring provides infrastructure support.
      • For example connection to different databases such as RDBMS database,MongoDb Database etc.
    • Spring is a Huge and Complex Framework
      • A single enterprise application can be built with many ways in Spring.
      • We use different combinations and configurations to build an application.
      • There are multiple setup steps
        • Spring can connect to MongoDb,RDBMS, it can connect to JDO etc.
      • There are multiple Build and Deploy steps in Spring.
AutoConfiguration
  • "@EnableAutoConfiguration" allows for the configuration classes to be dynamically scanned into the application context.
    • These configuration classes are based on the jars which is loaded on classpath usually via maven or gradle.
    • These are driven off from the spring.factories file that is in the meta-inf directory of each jar loaded into the application.
  • We can also control the order of Auto Configuration by following annotations
    • @AutoConfigureBefore
    • @AutoConfigureAfter
  • Conditional loading allows configurations to only be loaded based on conditions on availability and non availability of resources in an application.
    • If we want configurations to be loaded based on the classes in the class path we use following annotation
      • @ConditionalOnClass
    • We can also drive configurations based on the beans defined in the application context using following annotation
      • @ConditionalOnBean
    • We can also drive configuration based on the missing beans or classes via following annotation
      • @ConditionOnMissingBean
      • @ConditionOnMissingProperty
  • Many projects have preconfigured "default" properties for Auto-configuration classes.
    • "@EnableConfigurationProperties" specifies this property set and loads it.
    • For example if we load a database class like "H2" in classpath it will have enough configuration and configuration properties to load an embedded database into your application.
    • These properties can always be overridden.
  • There are also Application type based conditions
    • We can define type of Application(Web/Mobile) via these conditional Annotations.
  • We also have resource based annotations for conditional configuration.
  • We also have Expression based annotations for conditional configuration
    • Allows us to use Spring Expression Language to drive conditional expectations of our class regarding what gets loaded during ordered configuration.
  • SpringBootApplication class loads the default configurations in Spring Boot Framework
    • This file derives the start of Spring Boot Application.
Spring Boot Configuration
  • We can configure spring boot application during runtime or during startup time.
  • One way to change application configuration is by using properties
    • application.properties or application.yml file is used for this.
  • Configuration may change based on Data Center or Environment you are running.
    • So appliocation.properties or application.yml can only be used for dev purpose
  • Environment variables are very common for modifying the profiles that will be loaded.
  • Command Line Injections are helpful when we have more than one application running in an environment but serving different functions.
  • Cloud Configurations(config server,vault,consul) we can change the configuration for a cloud native based application suit instead of a single application.
  • Bean Configurations is done by Beans that are defined as a part of the application context.
    •  We can add beans to the default application class.
      • This will mess up the code as all the configurations will be at one place
    • We can also add beans to separate configuration classes
      • We can then load these to application context via component scanning.
      • We can define these configuration classes as something to import.
  • We can use xml based configuration files.
    • These are mostly used in legacy application as Java based Configurations are now a days most commonly used.
  • Java based annotations are included by component scanning beans in our application.
    • Any Component in a sub package is automatically component scanned.
  • Best way is to take a good mix of these approaches
Profiles
  • Helps to create flexible configurations based on different environments of an application.
  • All the different environments may have different settings in following use cases or components concerned
    • Third Party Dependencies
      • In non production environments we may use sandbox environments provided by third parties for example payment gateways.
      • Log Level Changes
        • In Dev we have log level set to debug
        • In prod we may set it to warn or error depending on our use cases.
      • Service Deployments
        • Dev server should point to webservices which are available for dev server only.
      • Internal Resource Deployments
        • Messaging systems like Rabbit or Kafka
        • Smtp and Ldap systems
  • Profiles help in achieving this without creating multiple containers.
    • This is also valuable where we have live and cold production domains
  • Spring Boot naitively provides support to yml files only.
    • Our application.properties is converted to application.yml
  • Instead of having properties file we can directly have yml files which can be distributed in different environments.
    • This provides us the flexibility to use same yml file among different profiles.
  • We use spring.profiles value as the key.We put this in our yml file.
    • Next whatever properties that go after this profile value belong to that specified profile.
  • To engage with any of the profile we use the key "spring.profiles.active"
    • We can inject this key value either from command value but in real world scenario we should use Environment Variables as we can set them at runtime.
application.yml
 spring:  
  profiles: dev  
 server:  
  port: 8001  
 ---  
 spring:  
  profiles: test  
 server:  
  port: 9001  
command line
 java -jar -Dspring.profiles.active=test target/initial-boot-app-0.0.1-SNAPSHOT.jar  
  • Note in above command line we have passed parameter -Dspring.profiles.active=test
    • Hence the application will run on port 9001
Spring Boot Actuator
  • Spring actuator works when you turn off security.
  • Next we need to enable various actuator endpoints in our configuration in Spring 2.
  • Some of the endpoints are
    • env
      • Shows application environment variables.
    • health
      • Gives the health of various resources
    • mappings
      • All request mappings are shown here.
  • There are many other endpoints like this
  • We must always hide actuator endpoints from public facing system.
  • It is always recommended to enable actuator endpoints in dev profile.
application.yml
 management:  
  endpoint:  
   env:  
    enabled: true  
   health:  
    enabled: true  
    show-details: always  
   beans:  
    enabled: true  
   metrics:  
    enabled: true  
   mappings:  
    enabled: true  
  endpoints:  
   web:  
    exposure:  
     include: '*'  
  info:  
   env:  
    enabled: true  
 spring:  
  profiles: dev  
 server:  
  port: 8001  
 ---  
 spring:  
  profiles: test  
 server:  
  port: 9001  

Spring Boot Default Web dependencies
  • There is no difference between HTML based web apps and web services in Spring Boot.
    • A single application can contain both.
  • Both require spring-boot-starter-web package
    • This package is a mixture of components that helps the apps.
  • Spring Boot maintains versions between the dependencies
    • It maintains right mix of dependencies from Spring as well as other vendors like Apache etc.
  • Tomcat server is one of the important components.
    • It serves as container to execute project jar files.
    • We can use undertow or jetty if needed instead of Tomcat
    • We can remove tomcat completely and create a war file instead of jar.
    • Default configuration is not a secure way to deploy specially when we are deploying on a public cloud.
  • Jackson Jason Marshaller is another component in spring.web
    • We get jackson libraries to marshal and unmarshal json.
    • Useful for Restful web services or reading file from a file system or files from a message listener that are structured in json format.
    • By default a Spring application serving a Responsebody or accepting a RequestBody we can get automatic Marshaling and UnMarshaling of the json. These can be customized by handlers depending upon use-cases.
    • We also get JSON path withntest dependency and by default we get test dependency if we build project from start.spring.io
      • Allows us to test json responses by looking at it from a XPath like structure.
    • Slf4J is included as a logging framework
      • Spring Boot Builds its own loggers.
      • We can leverage properties to modify logging,logging format or log level itself.
      • We also get a logback and jboss logging.
    • Spring libraries included are as follows
      • Spring Boot autoconfigure
      • 3 separate boot artifacts are included i.e. the tomcat starter,logging starter and boot starter.
      • We get spring core libraries like spring core,spring AOP,spring Beans,Spring Context,Spring Expression.
        • Spring Expression is used for conditional configuration and loading properties resources.
        • We get spring web and spring web MVC in order to do web operations.
    •  Other libraries included are
      • Snake XAML reads the yml files and convert them to properties at runtime execution.
      • We get bean and web validators(Javax and Hibernate)
    • Each starter throughout the entire Spring io page has its own set of behaviors and properties.
      • These properties bring in other starters as well we should have knowledge of all these starters.
Creating a Spring Boot Project
  • In pom.xml create a tag <parent> and inside parent add dependency with 
    • groupid: org.springframework.boot
    • artifactid: spring-boot-starter-parent
  • This declares that our project is the child of this parent project.
    • The parent child relationship between a projects is a maven concept.
    • Since for 80% use cases we can use Spring Convention for 20% we may require configuration.
    • This parent project is provided by the Spring Boot Library which contains all default configurations.
  • Next we need to setup dependencies
    • We need to add following dependency 
      • GroupId : org.springframework.boot
      • Artifact: spring-boot-starter-web
    • This will download automatically all the dependencies needed for a web project.
  • We can also create a Spring Boot Project simply by going to url start.spring.io
    • This is used to start off with Spring Boot Projects.
    • Select the type of project by choosing Maven Project(Choose the Project Management Tool).
    • Select the language you will be using for coding.
    • Select the version of Spring Boot.
    • Add the project Metadata
      • Add Group
      • Add Artifact
      • Search for dependencies and add them.
    • Some of the necessary dependencies are as follows
      • Spring Web
      • Spring JPA
        • allows us to use database in object oriented fashion
        • act as orm for the database
      • MySql
      • JDBC
      • ThymeLeaf
        • Template Engine.
    • Change the Description
    • Select Packaging Type
    • Select Java Version
    • Click on Generate Project
      • The project gets downloaded as zip file.
    • Inside the Downloaded Project Folder we have following Structure
      • pom.xml
        • manages dependencies for Maven
      • mvnw
        • used to install maven
      • src
        • main
          • Java
            • Will contain our java classes.Already has a spring boot starter class.
          • Resources
            • application.properties
              • application.properties is the properties file for our application.
            • static
              • used for js,css files
            • templates
              • used for our html files
      • test
        • Used for test cases
pom.xml
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  <modelVersion>4.0.0</modelVersion>  
  <groupId>com.springmvcimplant.springbootstart</groupId>  
  <artifactId>course-api</artifactId>  
  <version>0.0.1-SNAPSHOT</version>  
  <name>SpringMVCImplant Course API</name>  
  <parent>  
  <groupId>org.springframework.boot</groupId>  
  <artifactId>spring-boot-starter-parent</artifactId>  
  <version>2.1.6.RELEASE</version>  
  </parent>  
  <dependencies>  
       <dependency>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-starter-web</artifactId>  
       </dependency>  
  </dependencies>  
  <properties>  
       <java.version>1.8</java.version>  
  </properties>  
 </project>  
Configuring Spring Boot Properties File
 spring.datasource.url=jdbc:mysql://localhost/votingsystem  
 spring.datasource.username=root  
 spring.datasource.password=  
 spring.datasource.driver-class-name=com.mysql.jdbc.Driver  
 spring.jpa.hibernate.ddl-auto=create-drop  
Running Spring Boot on Java 9
An issue reported while handling XML in Spring Boot in Java 9 is regarding XML parser for that we may have to include following dependency separately.
           <dependency>  
                <groupId>com.sun.xml.bind</groupId>  
                <artifactId>jaxb-impl</artifactId>  
                <version>2.4.0-b180830.0438</version>  
           </dependency>  
Starting Spring Boot Application
  • Next we will create a class which will serve as a starting point for our application.
    • Add main method to this class.
    • In this main method we will bootstrap our spring boot application.
    • This will make it as a Standalone application.
      • This method creates a servelet container starts it and hosts java application in it.
    • Annotate the main class with "@SpringBootApplication" this will tell Spring that this is a Spring Application.
    • In main method we need to tell Spring Boot to start the application and then create a servlet container and host the application in Servlet Container and make it available.
    • Spring Boot has a utility in which we can do all this in just one line
      • The name of this Static Method is Spring Application.run(source,args)
        • The first argument is the class which we have annotated
        • The Second Argument is the argument passed to the main method.
      • This method performs the following operations
        • It sets up the Default configuration
        • Starts Spring Application Context.
          • Spring is the container for all the code that runs on our application server.
          • These include Business Services,Controllers,Data Services etc.
          • This container is called as application context.
        • Performs a class path scan
          • Code in Spring Boot is plugged in using creating classes and annotating them with intent.
            • We create a service and annotate it with @Service
            • We create a controller and annotate it with @Controller
          • Spring needs to perform class path scan to check the marked classes with respective annotations.
            • There is also metadata in these classes which helps Spring to provide information regarding the classes.
        • Starts Tomcat Server
  • That's all when we run we have a simple Spring Boot Application.
CourseApiApp.java
 package com.springimplant.springbootstarter;  
 import org.springframework.boot.SpringApplication;  
 import org.springframework.boot.autoconfigure.SpringBootApplication;  
 @SpringBootApplication  
 public class CourseApiApp {  
      public static void main(String[] args) {  
           SpringApplication.run(CourseApiApp.class,args);  
      }  
 }  
Creating Entity's by Data Definition Language using Persistence API
  • Create a new package for entities.
    •  This should be a sub package of the package that contains main class
  • Create entity classes within the package
  • Annotate the entity class with @Table(name="table_name") and @Entity
    • preferably use plural names for tables
  • To add an identifier use @ID
  • To create a column name corresponding to key use @Column(name="id")
  • Since we have included dependency "spring-boot-starter-data-jpa"
    • This will check sub packages of the package that has our main class for annotations related to entity creation.
 package com.springimplant.votingsystem.entity;  
 import javax.persistence.Column;  
 import javax.persistence.Entity;  
 import javax.persistence.Id;  
 import javax.persistence.Table;  
 @Entity(name="citizens")  
 public class Citizen {  
      @Id  
      @Column(name="id")  
      private Long id;  
      @Column(name="citizen_name")  
      private String name;  
      public Citizen(Long id, String name) {  
           super();  
           this.id = id;  
           this.name = name;  
      }  
      public Long getId() {  
           return id;  
      }  
      public void setId(Long id) {  
           this.id = id;  
      }  
      public String getName() {  
           return name;  
      }  
      public void setName(String name) {  
           this.name = name;  
      }  
 }  
Using Spring Data to create a Repository
  • Create a new package for Repository Classes.
    • It should be a sub package of the package that contains Main Class
  • Create an interface with name as {entityname}Repo
    • This should extend JPArepository interface<entity name,Identifier>
      • JPARepository interface contains all the functions that are needed to perform CRUD operations in Entity.
    • Annotate the class with @Repository.
    • Above your main class add @EnableJPARepositories annotation.
 package com.springimplant.votingsystem.repositories;  
 import org.springframework.data.jpa.repository.JpaRepository;  
 import org.springframework.stereotype.Repository;  
 import com.springimplant.votingsystem.entity.Citizen;  
 @Repository  
 public interface CitizenRepo extends JpaRepository<Citizen,Integer> {  
      public Citizen findByName(String name);  
 }  
Adding Controller to Spring Boot
  • A controller is a java class that has certain annotations mapped to it which help Spring in handling requests.
    • Annotation provides information regarding what URL access triggers it.
    • What method to run when accessed.
  • The web layer in Spring Boot application leverages a Spring Framework called as Spring MVC.
    • It lets us build server side code which maps to url's and provides response.
    • In our case since this is a REST Controller the response will be JSON.
  • We have added a controller class as shown below and annotate it with @RestController.
    • If we use a RestController we do not need to create a view.
  • Next we add methods to it with annotations of @RequestMapping(" ") which maps it to a url.
  • All these are Spring Web or Spring MVC concepts.
  • Note that our controller class is in a subpackage of the "SpringBootStarter".
    • This helps in putting the class in classpath and helps the Spring during classpath scan.
  • When the classpath scan happens the Spring automatically registers all the annotations for a Java Class file.
HelloController
 package com.springimplant.springbootstarter.controllers;  
 import org.springframework.web.bind.annotation.RequestMapping;  
 import org.springframework.web.bind.annotation.RestController;  
 @RestController  
 public class HelloController {  
      @RequestMapping("/hello")  
      public String sayHi()  
      {  
           return "Hi";  
      }  
 }  
Returning Objects from a Controller
  • Let us now create a controller which responds with topics information.
  • We create a new class in package Controllers called as topicController.
    • We create this as a @RestController.
    • We create a method which returns list of all topics.
  • We create a Topic class for this which serves as our entity.
  • Since TopicController is a RestController any object returned from method will be automatically converted to json.
TopicController
 package com.springimplant.springbootstarter.controllers;  
 import java.util.ArrayList;  
 import java.util.List;  
 import org.springframework.web.bind.annotation.RequestMapping;  
 import org.springframework.web.bind.annotation.RestController;  
 import com.springimplant.springbootstarter.entities.Topic;  
 @RestController  
 @RequestMapping("/topic")  
 public class TopicController {  
      @RequestMapping("/all")  
      public List<Topic> showAll()  
      {  
           List<Topic> topicList=new ArrayList();  
           for (int i=0; i<10; i++)   
           {   
                topicList.add(new Topic("Sno."+i,"Topic "+i,"Description for Topic "+i));  
           }  
           return topicList;  
      }  
 }  
Topic
 package com.springimplant.springbootstarter.entities;  
 public class Topic {  
      private String id;  
      private String name;  
      private String description;  
      public Topic() {  
           super();  
      }  
      public Topic(String id, String name, String description) {  
           super();  
           this.id = id;  
           this.name = name;  
           this.description = description;  
      }  
      public String getId() {  
           return id;  
      }  
      public void setId(String id) {  
           this.id = id;  
      }  
      public String getName() {  
           return name;  
      }  
      public void setName(String name) {  
           this.name = name;  
      }  
      public String getDescription() {  
           return description;  
      }  
      public void setDescription(String description) {  
           this.description = description;  
      }  
 }  
Creating View Files
  • We can use template engines or jsp files to create view files.
  • Below is an example of thymeleaf template engine view file.
 <!DOCTYPE html>  
 <html xmlns:th="http://thymeleaf.org">  
 <head>  
 <meta charset="ISO-8859-1">  
 <title>Insert title here</title>  
 </head>  
 <body>  
 Insert Your Name  
 <form action="#" th:action="@{/casteVote}" method="post">  
      <input type="text" name="name">  
      <input type="submit" value="submit">  
 </form>  
 </body>  
 </html>  
Adding Logging
  • Logging can be added as follows
  • In properties file add following lines
    • logging.level.org.springframework.web=info
    • logging.level.org.hibernate=info
  • In Controller file add the following
    • import org.jboss.logging.Logger;
    • public final Logger logger=Logger.getLogger(VotingController.class);
    • logger.info("Voting Started");

No comments:

Post a Comment

Spring Boot

What is circular/cyclic dependency in spring boot? When two services are interdependent on each other, that is to start one service, we requ...