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.
- "@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.
- 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
- 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.
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 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.
- 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
<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
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.
Creating Entity's by Data Definition Language using Persistence API
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 9An 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);
}
}
- 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
Adding Controller to Spring Boot
Creating View Files
- 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);
}
- 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.
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;
}
}
- 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