spring core + spring boot+thymleaf+microservices
spring core + spring boot+thymleaf+microservices
SPRING CORE
->To learn spring boot the minimum requirement is to know about spring core . if you
know spring core very well and foundation is clear then you are eligible to learn spring
boot and go a head.
->spring comes with various modules . and spring boot is top of all that means if we talk
about spring boot spring boot internally uses all of these modules. But to go ahead with
spring boot we should know atleast about spring core.
Note:- spring boot is not a new technology or framework or alternate for spring actually
spring boot internally uses all these modules only.
->before spring there is EJB but it was very complex to write so,ROD JOHNSON think how
to develop enterprise application without using EJB ,so to reduce complexity and increase
productivity he developed a framework called SPRING in 2003 so from that time to till
date spring and springboot is ruling the market.
Before go ahead with spring core ,let see the software requirement for spring
->in spring for configuration we can use Xml based configuration or annotation based
configuration. (annotation based recommended).
->Note:- as we know IOC container create and instantiating the object but we not use
word “Object” in spring because this object is managed by our IOC so we called it “Bean”
because its life cycle is managed by IOC.
->see when we develop any project let take example of spring project then we requires lot of libraries
which present in external source like MVN repository then if we manually download each and every
library then it take lot of time as well as version mismatch issue can also occur and lot of issue may come
so maven build tools is came into picture
->maven tool automatically downloads all the dependent libraries from mvn repo and import it to our
application without any version mismatch issue.
->this is not complete picture of maven but for as off now its enough.
Group Id:- you need to tell your project comes under which group ex:- suppose in your
company lots of project are developed related to finance department and this project also
related to finance only so you can say that this project comes under finance group that is
nothing but group id.
artifact id:-artifact id means here you need to tell purpose like your project belongs to
finance group but under finance there are so many things our project related to which
thing we need to specify here.ex:- under finance our project related to loan.
Package:-just specify project package in which package you need to put your
project.
->click on finish.
Note:- maven internally download all the dependency from maven central
repository.
->if you want any dependency just go to maven repo and copy dependency tag from
there at paste to POM.xml file maven itself download that in your project.
Ex:-
NOTE:- here i am using spring version 5.3.19 it is not mandatory to use same version
because in spring frequently new version is realised . if this version is not worked or
compatiable then try another version. Take any stable version by your own.
->we have created project but still it is maven project only to make it spring project and to
use spring core functionality we need to add spring-context dependency .to add this
add spring-context dependency in POM.xml.
Note:- maven first see in local repository in your system if it available there then it use it
from there otherwise it download from internet.
->maven also see version if dependency already present in local but it is not compatiable
with version then it download again from central repo.
->as of now we know how to create maven project and how to make it spring project by
adding spring-context dependency using POM file with help of maven build tool.
->we have also seen about IOC container .what is IOC ,what it responsibility now we will
see these topics indeep.
Overll small picture get cleared now go deep dive inside these topics..
Configuration file
->as we know in spring .IOC will create bean and provide it in our application
but we need to defined configuration regarding that means what kind of bean
we need so that IOC container/application context can full fill our demand.
->but where to keep that configuration XML file because we get one project
structure and there are to lots of different –different packages and folder..
</beans>
Now we have one class suppose
->we have Loantaxcalculator class and we need it object but we don’t want create
manually. we want that IOC contaire will create and give to us then we will defined
that in configuration xml file that we want that Loantaxcalculator bean.
myappconfig.xml
->we have created configuration XML file and also define <bean> tag that we need this
class bean, now give this configuration file to IOC container/application context.
ClassPathXmlApplicationContext: This container takes the path of xml file from the
classpath and loads the definitions of the beans from an xml file. means
classpathxmlapplicaioncontext will recoginized where this myappconfig.xml in the
classpath means in the project ..and read that configuration file and create its object.
->ApplicationContext is nothing but IOC container. Now in above code your
bean get created .now to use that bean we need to get it from IOC container
so we use getBean(unique_bean_id) method.
->create main class and create ApplicationContext as well and get bean with
that unique bean id.
->applicationContext will follow eager loading that means whenever IOC starts
immediately it will create bean objects.
->BeanFactory will create bean object on demand basis that means when we
call getBean() method then only it will create bean object (lazy loading).
->in general if you need to set class property value then we can simply set by
using setter and getter , but we want so set from configuration xml file then we
can set it by <property> tag inside bean.
Ex:
Myconfig.xml
Main class
Dependency injection
->as off now we have seen bean creation using configuration xml file. Now we
deep dive into most important topic that is DI (dependency injection).
Let first know what is dependency means. See if one class object requires or
need another class object for some operation or business logic then we can
say that one class is dependent on another class.
Ex:- we have one Car class and we have one Engine class then car class requires
Engine class object which means Car class is dependent on Engine class.
Ex:-
Note:-if we use <property> tag for injection then it uses setter method .which means
setter injection happens. The property name should match with the setter method
property name of the class. The ref bean value should match with bean id value in the xml
file.
We have seen how to set normal property using <property> tag and how to inject
dependent bean using ref attribute. Setter method injection is one way we have another
way also ..
Constructor arg:
<constructor-arg>
</constructor-arg>
->it will inject that bean using constructor . you can use both either setter or constructor
but in constructor injection you need to maintain constructor parameter order in which
order parameter are present in constructor in same order you need to pass value from xml
file.
->in constructor if by mistake parameter order changes then it will cause issue so to solve
it we can use one more attribute called index.
->now using index attribute it is not mandatory to maintaine order just you need to write
correct index
->as off now we have seen how to inject single dependency now we will see how to inject
list of dependencies
Using setter
Autowiring
->as off now in above cases we are doing manually wiring of objects means we are
injecting beans using <ref> tag and all inside property tag or constructor arg tag.
->but for small number of objects it’s ok but in real time there are lots of object we
require to inject then this manual wiring approach is not recommended just for ex if we
have 50 object then we need to write 50 bean tag and inject it .it become complex .
->to solve this autowiring came into picture. Auto wiring solve all the manual
dependencies specified in the configuration and make DI simple.
2)byType
3)constructor
Autowiring byName
-> The dependent property name (variable) in the class is matched with bean id in the
configuration file and if they are matched then ioc will inject that particular bean by using
setters simple
Autowire by Type
->in this dependent property type in the class is matched with the bean class type. If both
are matched then IOC container will inject that specific bean. We need to use
autowire=”byType”.
->Note:- if more then 1 bean is found with same class type in XML configuration
file,autowire byType give error. We can fix this in annotation based configuration.
->autowired byType means ico will match type not bean id so you can give any bean id.
Autowire by constructor
->autowire by constructor uses constructor for dependency injection.
->autowire by constructor first inject bean based on its type means if
type matched then it inject that particular bean.
Note:- we have seen that if more then 1 bean having same type then
autowire byType generate exception. But when we use autowire by
Constructor. Then first it matched on the basis of by Type but if ioc
found more then 1 bean with same type then IOC will try to match
constructor parameter name with bean id .if matched then it will
perform the injection otherwise raise an exception.
->to solve above problem annotation came into picture. Actually in java
annotation introduced from java 5. Now spring provides lots of annotation and
now IOC will read that annotation and perform its task now no need to
maintain separate XML file for that.
@Qualifier: if there is more than 1 bean with same class type, using @Qualifier
we can match the bean id to be injected
@Lazy : Indicates the lazy loading of Bean , can be used along with @Bean or
@Component
ApplicationContext context=new
AnnotationConfigApplicationContext(AppConfig.class);
->now if we want to inject some dependent object using annotation then we
can go with
@Autowired
Note:- by default @Autowired inject bean by matching ‘byType’ if same type
of bean is present then it inject on basis of byname. In annotation this single
annotation will work both byType ,byname.(in xml we need to mention separate
byname,ByType)
->as we know @Autowired work bydefault byType . if more then one bean
existed with same type then it goes with byname.
->if in case ioc not get any bean byname also then it cause issue.
Note:- if you not create any setter then it implicitly inject using internal setter using
reflection api concept.
@ Qualifier
->if there is more than 1 bean with same class type, using @Qualifier we can
match the bean id to be injected @Qualifier is placed along with @Autowired.
->means if we have more then 1 bean of same type then @Autowired will
work byName but if bean name also not match in that case it will cause issue.
We can use @Qualifier annotation and specify the name so now qualifier
name must match with bean name ,it doesn’t matter what ever is property
name
@Component and @ComponentScan
->@Component: Class Level annotation which will be detected by
@ComponentScan for creating Spring Beans.
->@ComponentScan: Scans for the @Components in the specified base package, default
base package is the package where @Configuration class is present.
->in case of @Configuration we need to declare @Bean annotated method to create bean
,but suppose we need 50 bean then we need to create 50 bean methods . but here we
have one another class level annotations i.e @ComponentScan and @Component
->now if you want bean of any class then declare that class with @Component
annotation so that IOC will automatically scan it and create bean for you.
->if you want to give another name of bean instead of class name then you can
provide in @Component(“name”).
@Primary: If we can declare @Primary in any of the @Bean/@Component,
then by default the bean
->if you have used both @Qualifier as well as @primary annotation then IOC
will give preference to @Qualifier first then @Primary.
Bean Scope
Singleton – Same object returned for the same bean id per application context.
Prototype – Different object returned for the same bean id per application context.
-> bydefault every bean is singleton ,if we need to define the scope of bean as prototype
,we should declare the scope of bean as prototype during bean declaration.
->in this different bean will created every time in per application context.
Lazy loading – Spring Beans are created during the context.getBean creation.
->by default it follows eager loading. Means bean are created during the time
of application context creation.
Bean Life cycle
@Autowired on Constructor
case 1:
case 2:
in the class with @Component if we have more than 1 parametrized constructor, then one
of the constructor should be @Autowired otherwise it will throw error.
case 3:
in the class with @Component if we have more than 1 parametrized constructor, then if
we decalre @Autowired on more than 1 parametrized constructor, it will throw error
case 4:
in the class with @Component if we have 1 parmeterized constructor and 1 default
constructor(constructor without arguments) then default constructor gets called if the
parmeterized constructor does not have @Autowired otherwise the parameterized
constructor gets called where @Autowired is present.
Spring boot
->Spring boot is an open source java-based framework developed by Pivotal
Team.
->spring boot was designed on the top of existed spring framework only it
internally uses all spring modules .
->spring boot can used to develop spring based application either by JAVA or
by Groovy.
->spring boot also provide build tool like Maven , Gradle to develop
application.
->it also provide In-Memory database also ex:- H2
Note:- if we are using plain spring then developer need to take care of
everything i.e business logic + lots of configuration.
Note:- if we are using spring boot then developer can focus on its business
logic and rest all configuration will be taken care by spring boot.
->spring boot is famous for auto-configuration feature which is one of the main
feature of spring boot.
Ex:- if we define web-starter ,spring boot will provide web related feature like
give support of server.
..etc.
->now just provide necessary information for your project like group,artefact
id,package name ..etc we already know about this in spring core.
->now you just need to open any IDE in our case (STS) and import it by clicking
on existing maven project .
By spring spring-tool-suit (STS)
->click on new then select spring starter project.
Note:-IOC will first search bean in base package and then sub-packages .if bean
is available in these 2 places then IOC will create bean. If bean is present in any
other separate package then IOC will not scan those beans until and unless we
not specify .
->but if we want that spring will scan different package also then we need to
override @ComponentScan() with basepackage parameter ,so that our IOC can
now able to scan all the packages specify there.
@Qualifier: if there is more than 1 bean with same class type, using
@Qualifier we can match the bean id to be injected .@Qualifier is placed along
with @Autowired
->we already learnt about these annotation in spring core which will be used in
spring boot also..
Spring banner
->when we run spring boot application we can see that spring logo is printing
on the console that spring logo is nothing but banner.
->we can also customize spring boot banner by creating banner.txt file under
src/main/resources
->if you want banner in same style then you can generate ASCII text and keep
it in banner.txt file.
->we have 3 modes for spring boot banner
o off
o log
o console
o ApplicationRunner
o CommandLineRunner
->to use runner just you need to implements these runner Interface to you
classes where you need to implement .
Usecase:-
->we can write cache logic on runner run() method means load data to cache
only once when application started.
->if we talk about JDBC developer need to take care about everything like
developer need to create connection, prepare statement for queries ,fire
queries using inbuilt methods, then at last close connection.
->spring JDBC built on top of jdbc only and it reduces lot of developer efforts
by taking care of db connections and db exceptions.. we just need to use it.
->To represent our application data in form of object we will go for ORM
framework like hibernate.
->to overcome this Spring ORM came into picture by providing abstraction
layer for hibernate. Spring Orm provide predefined Classes to execute
methods directly but still there is some limitation. predefined methods
redundant issue may come.
->To overcome this problem Spring Data Jpa came into picture.
->by using Data Jpa it is very easy and clear to implement persistence layer.
->Data Jpa is auto configured and self logic implemented for CRUD operation.
->spring boot also supports both sql and No-sql database also.
Step1. Create database in your Mysql database (in ourcase we are using
Mysql).
o Datajpa-starter
o Jdbc driver (in my case mysql if you are using Oracle then use that)
Note:- if in database table name and our entity class name is same then
@Table is optional.
Note:- if database column name and entity class field name is same then
@Column is optional.
o CrudRepository
o JpaRespository
CRUD Repository
Step6:- call the repository method and test it by save data in db as off now we
are calling it from main class in future we will call it from service.
=>if primary key value is Null or not exist in DB then perform insert
operation,else if record is already available then update operation.
->we have created one Entity class and used following annotations like
@Table,@Column,@Id,@Entity.
->we have created one interface and extends it with CrudRepository to make
Repo Layer.
Note:-for CrudRepository data Jpa will implement our interface using proxy
design pattern.
->above diagram shows example of few methods we have used to perform crud
operation.
Descending order
Jpa is used for Pagination
->it is used to reterive records based on conditions just for filter kind of thing.
->as off now we have seen CrudRepository as well as JPARepository and few
methods like save(),findAll(),findById,delete(),deleteAll(),deleteById() etc.
findByXXX ( ) methods
-> findByXXX ( ) methods are used to construct the query based on method name in the
repository
-> We need to write findByXXX ( ) method using entity class property name (variable)
Note: Method name is very important here because based on method name
only jpa will construct the query and it will execute that query.
Created_date
Updated_date
->Created_date column will represent when that record got inserted into
table.
-> UPDATED_DATE column will represent when that record got updated in
the table.
These column will help developer for analysis of insertion and updation in
future.
@CreationTimeStamp
@UpdateTimestamp.
Ex:-
Generators
-> Generators are used to generate the value for primary key columns in the
database.
->As we all already discussed in our database portion about primary key ,what
is primary key,use of primary key and etc.
->in real time when we develop application we should not ask end user to
enter value for primary key because end users may enter duplicate value
which may create ambiguity in our records.
->So we will use Generators to generate primary key column values with in the
application.
@GeneratedValue
@Column(name = "student_id")
-> When we insert record into table, sid value will be generated through
@GeneratedValue annotation
Note: MySQL Database will not support for sequences. MySQL DB will use Auto
Increment to generate the value for Primary key Columns
Transcation
->To understand transcation let understand this example
->we want to transfer money from source account to target account.
->To transfer money we need to perform two logic
1)we need to deduct money from source account
2)we need to credit /add money to target account.
->if both operation happen successfully means transaction is
succesfull.
But if we transfer the amount and amount deducted from source
account successfully but failed to credit the amount in target
account then our Transcation got Failed.
->we also discussed about Atomicity . that either All or None.
Means if amount failed to credit to target account then that amount
should come back source account this is called rollback.
->in Data JPA when we perform Non-Select Operation then
Transaction will be committed by default.
->it is not automatically rollback.
->if we want to rollback the transcation then we should use
@Transactional annotation.
Ex:-
Repos
->in plain spring developer need to take care lot of boilerplate code but spring
boot reduces lot of work because of “Auto-Configuration” functionality.
o Web Application
o Distributed Application
->generally Web application are used for C2B business which means customer
to business model.
->Embedded servers are built-in servers which are used to run our
application. Like in advance java here we no need to install apache tomcat
separate and add to project.
Note:- when we are using JSP as a view then only this jasper dependency
needed otherwise this step is not required (because springboot not provide
support of JSP so we need this ).
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
Note:- if we not add this jasper dependency and we are trying to using JSP file
then if we send request to our controller it will download that file instead of
displaying response.
->as we know in JSP we can write in normal JSP scriplet tag as well as JSTL also.
So we need to add one more dependency if we want to use JSTL .
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
->select “war” instead of jar . if you select war then springboot will provide
webapp folder. Otherwise you need to create it manually.
->we need to use @Controller annotation over our Controller class to make it
controller.
-> Bind controller class method to HTTP GET Request using @GetMapping
annotation.
Step1:-
Step2
Step6:-
Using Lombok
->as we know we need to create getter and setters and if required
then zero args constructor and parametrized constructor. But to avoid
all these writing part we can use Lombok also,so that Lombok will take
care of getter,setter,constructor and all , just we need to use Lombok
annotations.
Query Paramteres.
->Query parameter represent data in key-value format.
->Query parameter will present only at end of the URL.
->Query Parameter will start with ‘?’.
->TO use multiple query parameter we can use ‘&’ as a separator.
->To read query parameters from URL we will use @RequestParam
annotations.
Ex:-
Path Parameters
->Path parameter is also used to send data to server in URL.
->path parameter can be present any where in the URL ,not necessary to keep
at end you can place anywhere.
->to represent data in URL using path param we need to use placeholder.{}
->this spring web-mvc tag lib contains lots of tag which help to deal
with form data.
Ex:
<form:form/>
<form:input/>
<form:password/>
<form:select/>
<form:hidden/>
<form:error/>
->To bind java object to form we will use ‘modelAttribute’ attribute.
->we will follow this architect , here we are making service layer direct
class , we can also achieve loose cupling by using interface also if
required.
We can also use H2 database , H2 database is embedded database
provided by spring boot.
->to use H2 database we need to add H2 dependecy.
->Note:- H2 database is for POC(proof of concept) means just for
temporary purpose to test your concept as you shutdown your server
you will loose everything)
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
Model interface
->like we have seen how spring mvc uses ModelAndView object and
how we are adding data and view name to it, like wise
->we have one Model Interface and we can send data from
Controller to UI using Model Object.
->this also represent data in key-value pair.
->we can write controller using ‘Model’ interface like below to send
data from Controller to UI.
->in Model we no need to set view name by using any method .
directly return String your view name it is automatically understood.
->as off now we have seen spring MVC .that either you use
ModelAndView class or Model Interface they both return view file
name and dispatcher servlet give this view file name to View Resolver
to get location.
->means what ever string you return dispatcher thinks it like a view
file name and it passes it to View Resolver and then it is identified by
view resolver.
->but if you want to send response directly without any view File.
Then we need to bypass the step of ViewResolver means dispatcher
servlet directly give response no need to pass it to viewResolver.
->So to send response directly to User without any View File then we
need to use annotation called @ResponseBody.
Thymeleaf is a modern server-side Java template engine for both web and
standalone environments, capable of processing HTML, XML, JavaScript, CSS,
and even plain text.
Thymeleaf Engine
Thymeleaf Engine will parse Thymeleaf Template. It uses Java model data to replace the
positions marked on the Thymeleaf Template to create a new text in the HTML page.
Step1.
Step2
Step3
Step4.create controller
Step5: create html file in template depending upon what view name you are
returning means here i am returning “about” .
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
difference b/w application.properties & application.yml
->When we create spring boot application, by default project provides
application.properties files under src/main/resources folder.
Ex:-
Note:- be careful of spaces while writing .YML files .give proper spaces .
->but in case of YML , single yml file is sufficient to deal with all profiles.
Application.properties,application-dev.properties,application-
uat.properties,application-prod.properties.
Same we can also defined in .YML approach. In .YML we have two option
either you can create separate file for different profile or in same file also you
can manage.
->we need to define profile in base file that spring need to use which
environment file for configuration .
->if we not use any profile concept then we need to change our configuration
file every time dependents on environment but it is very bad approach to
change our configuration file in real time because if by mistake something
went wrong then it may cause big issue.
For test we have separate database config which related with database which
stores test data used for testing.
->so in base file you need to specify which environment specific file project
should used.
What are RESTFul Services ?
->Restful Services are used to develop “Distributed Application”. Which is
independent of any programming language as we already discussed above
distributed languages.
->we have already discussed about B2B how companies are doing B2B using
distributed applications.
->JSON format is trending in market as well all latest tech stack supports JSON
format.
XML
->XML stands for Extensible Markup Language.
->XML is also tag based language. Which represent data in elements like
Ex:- <id>111</id>
->elements tag are paired means contains start tag and end tags.
1) Simple Element
2) Compound Element
Ex: <id>111</id>
<student>
<id>111</id>
</student>
-> SOAP Webservices will support only xml format for exchanging data
-> RESTful services supports for xml and some other formats also like json.
->so to transfer/exchange data from one app to another app we need to
convert one type format to respective type Object.
Lets see how to convert XML to java Object and java Object to XML.
Marshalling & Un-Marshalling
->Marshalling & Un-Marshalling are called Runtime Operation.
->The process of converting java Object into XML is called as
Marshalling.
->The process of converting XML into java Object is called as Un-
Marshalling.
Note: These operations will happen when the application is running
-> From Java 11 onwards JAX-B removed from JDK, we have to add JAX-B
dependency in pom.xml.
->in program we are just focusing on marshalling (java obj-- > XML).
->then in main class create Marshall object and just pass object and file name
with xml extension it will create file .
In spring 2.x
un-marshalling (xml to java object)
Here we using unmarshal() methods. Which again converts xml into object.
JSON
->JSON stands for javascript object Notation.
->as compared to XML ,JSON is light weight (it occupies less memory).
->with in { and } , JSON object contains multiple elements where each elements
represent properties.
-> In Java we don't have direct support to work with JSON data
-> We have third party apis to work with JSON data in java applications
o Jackson Api
o Gson Api
-> Using above third party apis we can convert Java Object to Json and Json to
Java Object.
However, the toJson method in Gson doesn't have an overload that directly
takes a File as a parameter.
You should first convert the object to a JSON string using toJson, and then
write that string to the file.
Now JSON to java Object
->above code we have pass json string directly. We can also pass
FileReader as an parameter see below
HTTP Protocol
->HTTP stands for hyper text transfer protocol.
->Http is a kind of medium or we can say mediator protocol between client &
server.
->in client server-architecture . client will send HTTP request to server and
server will process that request and send HTTP response back to client.
HTTP Methods
->there are several method which help us to deal with http
request/response
o GET:-it is used to get response from the server.
o POST:-it is used to send data to server(used in creation purpose)
o PUT:-it is used to update record at server.
o DELETE:-it is used to delete the record at server.
->When we deal with REST API and all then we need to bind Our
controller end methods with these HTTP protocol methods.
Ex:-
GET -----> @GetMapping
POST -----> @PostMapping
PUT-----> @PutMapping
DELETE----> @DeleteMapping.
Request/response contains two major parts i.e
o Header (it contains metadata)
o Body(it contains payload (business data))
Some HTTP Status Code
-> Response Header will contains HTTP Status Code. When we send response.
->actually this status code give information that how our request get
processed .every thing fine or not.
1xx - INFORMATIONAL
2xx - OK (Success)
Note: Http Status Codes will play very important in distributed applications
development
Note: POST, PUT and DELETE Methods having request body. GET method don't
have request body. Because get is used to send data to server and rest of them
used to send data.
-> Using ResponseEntity class we can construct Response with body and status
code.
Note: REST API Methods should have Unique URL Patterns otherwise we will
get ambiguity problem. We need to make sure our methods should be
identified uniquely.
-> To send (small piece of data like ld,key or etc) data to server in GET request
we will use below 2 options
1) QueryParams
2) PathParams
- spring-boot-starter-web
- spring-boot-devtools
2) Create RestController class using @RestController annotation
Ex : Accept = "application/json"
Based on "Accept" header REST API will send response to client in that format.
Internally "HTTP Msg Converters" will be used to convert the object data into
client understandable format.
=> "Accept" header represents in which format client expecting response from
REST API.
-> "consumes" represents in which formats REST API method can take input
data.
Swagger
->Swagger is third party api
->To use Swagger in our project we need to add some dependencies to our
project.
Swagger implementation for spring 2.xx version.
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.6.1</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.6.15</version>
</dependency>
URL:- localhost:8080/swagger-ui.html
As we know earlier that we can create distributed application
for B2B . In which one application which provide services is
producer application . and another application which
consumes that services is called consumer application.
-> The application which is accessing REST API is called as REST
CLIENT.
-> In Spring Boot we can develop REST Client in 2 ways
Synchrnonus
->after sending a request it will wait for the response to proceed further.
Usecase of synchronus client:- see above diagram in this our client app is
developed to show weather info on the basis of zip code.
->so we have one another app which provide zipcode on the bases of city
name and we have one another app which provide weather info on the basis
of zipcode.
->so we can use here synchronus kind of thing because until we don’t have
zipcode no use to hit weather info provider api.
->so after sending the request for zipcode wait for response until response not
come execution will not move further.
asynchronous
program to handle multiple tasks simultaneously rather than executing
them one after the other. Means execution will not wait for response of
other task .
->here no api are related then why to wait for response of one api . so in this case we can
go with asynchronus.
Ex:- RESTTEMPLATE
Exception Handling
-> Exception means an unexpected and unwanted situation occuring the
program execution is called as Exception as we already discussed in core java.
->as we know code which have chance of exception we put inside try block.
->To handle exception of any class in project level then we go for Global
Exception Handling. We use @RestControllerAdvice annotation for Global
Exception handling.
->in Controller based handling we create handler methods but that handler
method is specific upto that handler only means if we have 5 controllers then
separately we need to maintain handler method in each controller .code
redundancy may occur . suppose for NullPointerException we create separate
handler in first controller as well as in second controller separate .Our code will
work fine but handler method duplication occur.
->in Global handling technique we create separate class which is dedicated for
handling Exception occurs in any where in our application. Inside this class only
we define different-different handler method based on exception.
->as monolith application contains all the functionality it will become heavy
jar/war .
Advantage of Monolith
->simple to develop
->easy to understand.
->less configuration.
Dis-Advantage of Monolithic.
->Difficult to maintain.
->single point of failure:-if any error occur in project then entire project may get failed /down .
->for every major functionalities we create one microservice which fulfill that
functionality.
Advantages:-
->No –single point failure:- a failure in one microservice does not affect other
microservice. This is also called Resiliency.
Disadvantages of Microservices
->high budget required .business wise not recommended for small scale
projects .
**********Microservices Architecture**************
-> We don't have any fixed architecture for Microservices
-> Most of the projects will use below components in Microservices Architecture..
->it provides the details of all the services (microservices) which are
registered with Service registry.
->we can easily identified how many services available in the project.
->we can identify how many instances available for each service.
Services
->Services means REST API/Microservice.
->In project ,some services will interact with 3rd party rest API.
(if one service communicate with any 3rd party service then we call it external
service communication . we perform it using by RestTemplate , WebClient).
->In the project, some services will interact with another service with in
project then we call it inter-service communication. To perform it we use fient-
client .
->To distribute the load. We can run one service with multiple instances.
API Gateway
->API Gateway is used to manage our backend api’s of the project.
->API Gateway acts as mediator between end users and backend api’s.
->API gateway will contain Routing logic (which request should go to which
rest api’s).
Small example:-
Note:- bydefault port for eureka is 8761. Which means all the eureka client will
automatically detects this service registry and register .
Now just access this eureka dashboard. As off now no client service is registered in it we
need to configure that services and run them also .
Hit:- http:localhost:8761
Create services which need to register with eureka service registry.
Service 1:
Service 2
What if we change eurka service registry port other then 8761 ?
->suppose now our eureka is running on port 9090 then. In this case our services will
unable to automatically regestired it self then we need to add these config to properties
files in every eureka client service.
eureka:
client:
serviceUrl:
defaultZone: http://localhost:9090/eureka
->in these both we need to defined endpoint in hardcode way. What ever end-point we
define it hit that api and communicate. Which is fine . but to achieve load balancing these
both will not full fill requirement.
->in load balancing one api is running on multiple instances. So feign-client is designed in
such a way that it pick api name from service registry and internally it perform load-
balancing if one api is running in multiple instances. It using round-robin approach.
**********API Gateway******************
->as we discussed API Gateway will act as a mediator between client request and
backend.
->Api gateway will provide single entry point to access our backend api.
1) Filters
2) Routing
Filters:-Filters are used to execute some logic before request processing and
after request processing.
-> eureka-client
-> cloud-gateway
-> devtools
-> We can validate client given token in the request using Filter for security
purpose
-> Filters are used to manipulate request & response of our application
->To Configure actuators in our applications spring boot provided below starter
->Note:- by default actuator exposes only health endpoint . to expose all endpoint we
need to configure one property in properties file.
->you will get all end points now from here you can see any info regarding app.
4) Access application URL in browser (We can see Admin Server UI)
Working with Admin-Client
a) starter-web
b) starter-actuator
c) admin-starter-client
d) devtools
3) Create Rest Controller with required methods
Circuit Breaker
-> Circuit Breaker is a design pattern in Microservices
-> Fault-tolerance system means when main logic is failed to execute then we
should execute fallback logic to process client request.
Usecase example
get data from redis
Note: If redis logic is failing for 3 requests continuosly then execute db logic for
30 mins. After 30 mins re-try for redis logic execution if it is working then
execute redis logic only. If 3 re-try executions failed with reds then execute db
logic for next 30 mins.
POM.XML
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-
4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.6</version> //or use 2.5.4
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>circuitapp</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<spring.cloud-version>2020.0.3</spring.cloud-version>
<spring-cloud-starter-netflix-hystrix.version>2.2.8.RELEASE</spring-cloud-starter-netflix-
hystrix.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>${spring-cloud-starter-netflix-hystrix.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder-jammy-base:latest</builder>
</image>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Starter class
@SpringBootApplication
@EnableHystrix
public class CircuitappApplication {
Controller
@RestController
public class MyController {
@GetMapping("/data")
@HystrixCommand(fallbackMethod = "getdb", commandProperties = {
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "3"),
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),
@HystrixProperty(name = "circuitBreaker.enabled", value = "true") })
public String getData() {
System.out.println("getting data from redish.............");
int nextInt = new Random().nextInt(10);
if (nextInt <= 10) {
System.out.println("---------------- "+nextInt);
throw new RuntimeException("redish down..");
}
Sleuth is another tool from the Spring cloud family. It is used to generate the trace id, span id and
add this information to the service calls in the headers and MDC, so that It can be used by tools
like Zipkin and ELK etc. to store, index and process log files.
-> If we add Sleuth dependency in REST API then it will add span-id and trace-id for log
messages
-> If one request is processing multiple REST API then Sleuth will use same span-id for
REST APIs to generate log message.
-> By using span-id and trace-id we can understand which REST api has taken more time
process request.
-> To monitor span-id and trace-id details we will use ZipKin server.
-> Zipkin server is providing user interface (UI) to monitor all the details.
Note: The REST APIs which are having sleuth dependency should register with Zipkin
server.
Controller
@RestController
public class MyController {
@GetMapping(value = "/all")
public String getAll() {
logger.info(" **** getAll execution started ****");
String msg = "Welcome to codeminetech...!!";
logger.info(" **** getAll execution ended ****");
return msg;
}
}
Pom
<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-
4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>zipkidemo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<spring-cloud.version>Hoxton.SR8</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder-jammy-base:latest</builder>
</image>
</configuration>
</plugin>
</plugins>
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
Spring boot 3.xx (we not use sleuth we use zipkin with following config)
Controller
@RestController
public class MyController {
@GetMapping(value = "/wel")
public String Wel() {
logger.info(" **** wel() execution started ****");
String msg = "Welcome to codeminetech...!!";
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject("http://localhost:8080/msg", String.class);
properties
server.port=9090
# Zipkin configuration
spring.zipkin.base-url=http://127.0.0.1:9411/
spring.sleuth.sampler.probability=10
spring.application.name=welcome
poM
->when you select zipkin dependency in springboot 3.xx then these 3 dependecies will
come.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter-brave</artifactId>
</dependency>
->just run zipkin server from cmd and run our project.
SONAR QUBE
->Code quality and Security are vital to the success of any organization . in organization
both junior and senior developer work together in a project in a team. So junior developer
can write code which is not up to mark . then senior developer need to do code review . so
that quality code will go to live production environment.
->To maintain the code standard and quality code review must done frequently.
->when we talk about code review then Sonar qube tool comes into picture. Sona qube is
a code quality assurance tool that perform in-depth code analysis and generates an
analysis report to ensure code reliability.
Install sonarqube
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.4.0.905</version>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder-jammy-base:latest</builder>
</image>
</configuration>
</plugin>
</plugins>
</build>
</project>
->make controller and all
->start sonarqube server
-> For project do maven build with below goal To Do Code Review
mvn sonar:sonar