Spring Boot is a framework / utility that runs on top of the actual Spring Framework.
- Makes our life easy
- in what way?
- Rapid Application Development (reduced time) to remove the challenges we had faced during the Application Development Cycle.
- Having some sensible default values. And, remember most/all of them can be overridden either by the Configuration or through Code.
- Embedded Server :
Tomcat
- Tomcat Port # :
8080
- JPA - Form ORM, it uses
Hibernate
as Implementation of the JPA etc., Slf4j
for the logging framework.json
is the automatic conversion of an Object as a Response - via thestarter-json
- Embedded Server :
Note: In Spring boot, the configuration for all the defaults or other additional properties, is
application.properties
, available under thesrc/main/resources
directory.
- Configuration Hassles
- Earlier, we had to configure everything in XML (
spring.xml
file) - Initial days - Later, we had moved to Annotations (
@Configuration
,@Component
,@ComponetScan
etc.,) - For a Spring MVC project, we had to specify all the dependencies manually with the corresponding version numbers
of each dependency in the
pom.xml
file.
- Earlier, we had to configure everything in XML (
- Deployment
- We had to explicitly prepare a
.war
file and deploy it in Tomcat. - With the Maven Tomcat plugin, it was reduced to an extent, but still we had to perform manual steps.
- We need to explicitly add a Maven Tomcat Plugin in the
pom.xml
file.
- We need to explicitly add a Maven Tomcat Plugin in the
- We had to explicitly prepare a
- No configuraiton. It works by Convention.
- Embedded Application Server (Embedded Tomcat) - the Tomcat is bundled within the Spring Boot Library depends on the starter package we choose.
- No need to mention the version of any dependency. The parent pom takes care of the version of all the dependencies, and now the responsibility of maintaining the right version is shifted from the Developer to Spring Boot.
- It has got a few starter projects- which will have the necessary dependencies that are commonly required, to save the time of the Developer.
- Web -
springboot-starter-web
: It contains all the libraries required for a common Web Application including the Web Container like Tomcat , Jetty etc.,- Java EE Web, JSON Support, Tomcat, etc.,
- Rest is inclusive in Web.
- Data -
springboot-starter-data
: It contains all the libraries required for the Data Management- Spring JDBC, MySQL, H2 (In Memory database) etc.,
- Data JPA -
springboot-starter-data-jpa
: It contains all the libraries required for the Data Management using JPA - Java Persistence API - using ORM (Object Relational Mapping).- Spring Data JPA, Hibernate, etc.,
- Test -
springboot-starter-test
: It contains all the libraries required for the Unit and Integration Testing, including the Mocking frameworks.- JUnit, Mockito, etc.,
- Dev Tools - It is an interesting and most liked feature introduced in Spring Boot which will automatically scan for the changes you made in the IDE (Eclipse, Spring Tool Suite (STS), Intellij IDEA) and deploy it in the Web Container, there by the manual efforts of the Developer.
- No need of Stop the Server, Clean Build, Deploy it in the Server steps!
- Actuator - It is again an useful plugin for monitoring the end points and the health status of the Application.
- Web -
Note: Spring Boot works on CoC - Convention over Configuration methodology.
# It is just a plain old *Java Properties* file.
# No different/special for Spring, except that the IDE offers a context sensitive help
# for the keys.
#
# Any changes we make in this file requires a Server Restart.
# The properties file will be read ONLY ONCE during the Bootstrap/Starting phase.
server.port=9001
# ViewResolver component
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
No different from the Spring MVC REST, except the JSON representation comes by default, due to the fact that Jackson API is added automatically by the starter parent springboot-starter-web
!
It is also no different from Spring MVC, except the following.
Though the Spring Boot has Tomcat as a default Embedded Container, it does NOT have a support for the JSP as a View Technology in MVC.
We need to add the tomcat-embed-jasper
dependency manually in the pom.xml
file, as follows.
<!-- https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-jasper -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<!--<version>11.0.0-M4</version>-->
</dependency>
Note: The version is NOT required or recommended when using it along with Spring Boot, as it automatically downloads the right and compatible version of the library along with the other relevant ones.
We need to have all the .jsp
files inside the following structure.
Note: We should first create the folders
/webapp/WEB-INF/views
in the directory/src/main
/src/main/webapp/WEB-INF/<folders>/*.jsp
Example:
/src/main/webapp/WEB-INF/views/index.jsp
We need to add the View Resolver component attributes in the application.properties
as follows.
NOTE: Upto
/src/main/webapp
will be considered automatically.
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
NOTE: It is exactly the same way we configured as a
<bean>
element in theregistration-servlet.xml
for the spring-mvc-demo project to add theInternalViewResolver
-
You should have a class marked with
@Controller
(and NOT@RestController
) -
Add a method marked with
@GetMapping
annotation that returns aString
which is nothig but the logical view name.
The Spring MVC internally computes the full path to the JSP file - with the help of the ViewResolver
- what we configured now in the application.properties
by picking up the prefix
, and suffix
.
@Controller
public class HelloController
{
@GetMapping("/")
public String index()
{
return "index";
}
}
Note. Upon hitting the URL
http://localhost:8080/
, Spring MVC will transfer the control to theindex()
method of theHelloController
and picks up the return value as a String -index
, and then it completes the full path to the JSP page - `/webapp/WEB-INF/views/index.jsp' with the help of the View Resolver.
What if we have a same URI mapped to two different methods ? - http://localhost:8080/
@Controller
public class HelloController
{
@GetMapping("/")
public String index()
{
return "index";
}
}
@RestController
public class HelloRestController
{
@GetMapping("/")
public String sayHello()
{
return "Hello from SpringBoot Rest";
}
}
Issue :
Spring cannot decide which one to map for, as it is now an ambiguous mapping!
Solution
We need to decide which one to be mapped for the URI pattern - Web Controller or the Rest Controller?
We would prefer to let the @Controller
take over the responsibility of handling the http://localhost:8080/
- URI endpoint, than the @RestController
Reason:
-
Ideally, the URI
http://localhost:8080/
does NOT give any clue or other parts in the URI, it just has a "/". In this case, it will be the good starting point for a Web Controller to show the Home Page. -
For the
@RestController
, we would prefer following the best practices OR the convention of prefixing the URIs for the Rest with/api/
.
As the /api
prefix is missing in this URI, the @Controller
is deemed a best choice.
Note: Legally, any of the controllers can take up this request. There is no hard and fast rule the ONLY a Web Controller can respond to the URIs ending with just a "/", and it is just a commonly agreed practice and the strategy.
- JDBC - Java Database Connectivity
- JPA - Java Persistence API
JDBC
Using a Driver class, we would perform the step by step activities to talk to the database and manipulate the data. JDBC Program is an example.
JPA
Java Persistence API is a Specification that helps us achieve the data manipulation into the permanent storage (Database) which is non-volatile (sustains the reboots!), via ORM - Object Relational Mapping.
NOTE :
Volatile
- means Temporary. The data stored in the
variables of a Program will cease to exist, once the Program execution completes.Non-Volatile
: means Permanent - the data stored in a File System or a Database which will sustain the reboots of an Applicaiton or the Server, as the data is not stored inside the application, but outside of it.
ORM
ORM
(Object Relational Mapping) is a technique by which we can associate or map
the information stored in the Database Table - typically we speak about RDBMS (Relation
al Database Managemet System) to the Object
s in Java.
- Object
- Relational
- Mapping
It is a simplified mechanism to ease the Java developers, as they can still continue to be on the Java world, than stepping out to the different world - RDBMS - while dealing with the Databases that are of Relational in nature (RDBMS).
ORM Vs JDBC
- JDBC lets us talk to the Database via
java.sql
package through the Interfaces (most part) and a few classes -Connection
,DriverManager
,Statement
,ResultSet
andSQLException
etc., and we write a lot of Java executable statements to establish a connection and initiate a transaction with the Database, while catching the exceptions thrown if any by the JDBC Driver.
NOTE: The JDBC Driver is specific to the Database. We had
mysql-connector-v-x.y.z.jar
for the MySQL Database in a Java Program.
- ORM lets us talk to the Database via plain Java objects, and NOT through the JDBC!
Person p = new Person("Rama", "Vemulapalli", 26);
personDAO.save(p); //this line does the *magic* of storing the Domain object into the Table.
JPA Vs ORM
- ORM - let us use Java Objects
- JPA - uses ORM and a Repository pattern to have a common set of methods which are frequenly used by a Developer for the CRUD operations.
Client (UI/Browser) <--> Controller <--> Service <--> Repository/DAO <--> JDBC <--> Database
Clients
- Browser that knows to handle the HTML + CSS + Javascript - to deal with the User Inteface
Client (RestClient) <--> Controller <--> Service <--> Repository/DAO <--> JDBC <--> Database
Rest Clients
- Browser (No UI though)
- Dedicated Rest Clients
- Command line
cURL
HTTPie
- GUI
Postman
Insomnia REST
- Command line
This segment also can have two differnt flavors - Web and Restful.
Client <--> Controller <--> Service <--> Repository/DAO (Spring Data JPA) <--> JDBC <--> Database
Note: The Repository layer is actally served by the Spring Data JPA.
JPA - on top of ORM which indeed acts on top of JBBC where each of them act as a wrapper to the layers below.
Connection
DriverManager
- JDBC
Driver
Statement
/PreparedStatement
/CallableStatement
ResultSet
SQLException
Database
Schema
Table
Column
- Constraints - Integrity Constraints - UNIQUE, PRIMARY KEY, FOREIGN KEY etc.,
- Association
1:1
(One to One)1:m
OR1:n
(One to Many)m:1
- (Many To One)m:n
- (Many To Many)
Note : MySQL uses both interchangeably, but in other Databases like Oracle, DB2 - these are two different terms where Schema is a logial grouping of tables inside a Database.
Topic | JDBC | JPA / ORM |
---|---|---|
Database | Database |
Database |
Table | Table |
Entity |
Column | Column |
Column |
ER Diagram - Entity Relation Mapping.
- Using JPA APIs, via Java methods.
- Using the specialized
Annotations
underjavax.persistence
- as part of the JPA API@Entity
- apply at a Class level@Column
- apply at a Field level inside a class.
- JPA is a specification - conceptual level
- Hiberate is an implementation of the specification.
Ideally you would need Hibernat JAR file to use this JPA in the Application.
Note: Hibernate is one of the many implementations the JPA Specification - example, EclipseLink, iBatis, Open JPA etc., . However it gained a lot of popularity than others in the market.
JTA stands for Java Transaction API. It just has the API to manage the transactions in order to maintain the ACID properies
- A -
Atomicity
- C -
Consistency
- I -
Integrity
- D -
Durability
*jboss-transaction-api - This is an implementation of the JTA API.
Sl No | Specification | Implementation | Remarks |
---|---|---|---|
1 | JPA - says ONLY what |
Hibernate - ORM - says about how !! |
|
2 | JTA | JBos Transaction API | Hibernate - ORM - says about how !! |
-
Declare the dependencies in the
pom.xml
file of the Maven project - with Spring Data Starter, MySQL JDBC Connector. -
Update the Maven Project
-
Declare a class with
@Entity
and approrpriate@Column
Annotations
- Rule; At least one member of the Entity class should be annotated with the
@Id
of typejavax.persistence
!
- Specify the property / configurable values in the
appilcation.properites
for specifying the JDBC URL, Username, Password etc, for the database we intend to use - MySQL here.
## ---------------------------------------------------------
## Database related properties
## ---------------------------------------------------------
# Remember, if you use a non-embedded database like MySQL,
# the database must be created first. Only for embedded databases
# like H2, HSQL etc., the database gets created automatically.
spring.datasource.url=jdbc:mysql://localhost:3306/springboot_jpa
spring.datasource.username=raghs
spring.datasource.password=RaghsMySQL12#
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
#spring.jpa.show-sql: true
spring.jpa.hibernate.ddl-auto=update
## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
-
Invoke the relevant APIs from Spring Boot in the Test Class
-
Execute the Code.
A boundary that specifies/ demarcates the list of the operations which should be treated for the Transaction, which can take any of the two forms.
Commit
- Permanently store the changes into DBRollback
- revert back to the older stage if there is a failure or uncertainty.
Client <--> Server (Controller) <--> Service <--> Repository <--> JDBC <---> Database
Commit
Client <--> Server (Controller) <--> Service <--> Repository <--> JDBC <---> Database <--> [V1.0]
Client <--> Server (Controller) <--> Service <--> Repository <--> JDBC <---> Database <--> [v1.1] (Confirm the transactions permanently, v1.0 becomes 1.1)
Rollback
Client <--> Server (Controller) <--> Service <--> Repository <--> JDBC <---> Database <--> [V1.0]
Client <--> Server (Controller) <--> Service <--> Repository <--> JDBC <---> Database <--> [v1.1] Perform the operation
Client <--> Server (Controller) <--> Service <--> Repository <--> JDBC <---> Database <--> Error happens
Client <--> Server (Controller) <--> Service <--> Repository <--> JDBC <---> Database <--> [V1.0] (Rollback to the previous snapshot/version)
Let us say a banking transaction for a fund transfer example, we perform the following operations
1. Get the Source and Target Accounts, Amount to transfer
2. Check the Account Balance in the Source Account and ensure that it has got the sufficient amount to withdraw/transfer.
2. a. If there is an error, cancel the transaction and exit.
2. b. If so, transfer the funds from Source to Target Account as follows.
3. Perform a Debit operation in the Source Account of X amount.
4. Perform a Credit operation in the Target Accunt for X Amount.
5. If there is an error while performing any of the steps 4 or 5, we should revert (rollback) the transaction and keep the balance in both of the accounts intact.
- Bring the two critical transactions (Debit and Credit) - into the Transactional Boundary (mark them with
@Transaction
) - These two will be separate DB calls to the Repository from the Service layer OR the Controller Layer.
- Preferred to have a Service Layer which can help us do the
@Transactional
operations.
Repository Layer
@Repository
public class AccountDao [AccountRepository]
{
public boolean checkBalance(String acctNo, long amount)
{
//logic to check the balance in the account and it is permitted to be trasacted on the `amount`
return true;
}
public void withdrawFunds(String acctNo, long amount)
{
//transaction to withdraw amount from the acctNo.
}
public void addFunds(String acctNo, long amount)
{
//transaction to add amount to acctNo.
}
}
Service Layer
@Service
public class AccountService
{
@Autowired
public AccountRepository acctRepoistory;
@Transactional
public void fundTransfer(String srcAcct, String targetAcct, long amount)
{
//0. checkBalance
acctRepository.checkBalance(srcAcct, amount);
//1.withdraw
acctRepoistory.withdrawFunds(srcAcct, amount);
//2. add
acctRepoistory.addFunds(targetAcct, amount);
}
}
This property spring.jpa.hibernate.ddl-auto
specified in the application.properties
file is equivalent to hibernate.hbm2ddl.auto
in the persistence.xml
file in the earlier scenarios when we work with Hibernate direcly from a Java application.
It takes the following values as modes.
Sl # | Mode / Attribute | Description | Default |
---|---|---|---|
1 | create |
Create the schema and destroy previous data. | N |
2 | create-drop |
Create and then destroy the schema at the end of the session. | Y when we use the Embedded DB like h2 , HSQL or Derby etc., and when no schema manager was detected |
3 | update |
Update the schema if necessary. Most preferred in Production, as this will UPDATE the Table Structure ONLY when there is a structure change in the DDL statements declared in the Java Entities |
N |
4 | validate |
Validate the schema, make no changes to the database. It will actually compare the Database schema and the Java classes marked with the JPA Annotations like @Entity , @Column , @OneToMany , @ManyToOne for associations, it would throw an error and stop if there are changes. Otherwise, it does nothing. |
N |
5 | none |
Disable DDL handling | Y when no attribute is specified and the database is a non-embedded one. |
Note : Base Package for all the Interfaces and Classes : org.springframework.data.repository
Type | Parent | Actual class | Methods | Remarks |
---|---|---|---|---|
I (Interface) | None | Repository<T, ID> |
None | Marker Interface, and hence no methods declared.
|
I (Interface) | Repository |
CrudRepository<T, ID> |
|
All methods are related to the CRUD Operations, and all are self-explanatory The actual implementation class is SimpleJpaRepository which is defined in a sub package org.springframework.data.jpa.repository.support , and has the default implementation for all the methods declared in the CrudRepository Interface, that it implements. |
- Application Properties - Official Reference - https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html