Spring Boot With Microservices
Spring Core module
dependent and dependency class:
Has-a relationship is established if you create an object
one class within another class.
For example:
class Customer {
Policy policy = new Policy();
}
The relationship is Customer has-a Policy.
If a class wants to take the support of
another class then this class creates an
object of the another class inside it.
For example,
class OrderService {
InventoryService inventory= new
InventoryService();
}
OrderService has to check the inventory
before placing the order. So, OrderService is
taking the support of InventoryService.
OrderService is the dependent class, which
depends on InventoryService class.
OrderService : dependent class / target class
InventoryService: dependency class
Tell me who is the dependent and
dependency class?
ex: class UserService {
PasswordEncoder encoder = new
PasswordEncoder();
}
UserService : dependent class / target class
PasswordEncoder : dependency class
A dependent class can have multiple
dependencies also.
ex:
class OrderService {
InventoryService inventory = new
InventoryService();
TaxService tax = new TaxService();
}
tightly coupled and loosely coupled classes?
ReportService : dependent class
PdfReportCreator: dependency class
Suppose, If ReportService object has to print
the report in excel format, then what to do?
Answer is, do some code changes in
ReportService class. Remove the
PdfReportCreator object and add
ExcelReportCreator object.
Suppose if ReportService object has to print
a report in chart format then what to do?
Answer is, replace ExcelReportCreator object
with ChartReportCreator object.
Here, The ReportService class is tightly
coupled with the dependency object.
Everytime, when the dependent class wants
to change the dependency class, the code
changes are necessary.
To achieve the loose coupling between the
dependent and its dependency objects, the
classes has to be designed like below.
1. create an interface and define the
dependency classes by implementing that
interface.
2. In the dependent class, create an interface
reference variable to store the dependency
object.
3. Define a setter method to assign/set the
dependency object.
Here, you can set either
PdfReportCreator/ExcelReportCreator/ChartRep
ortCreator object to the ReportService object,
by without making any code changes. This is
called loose coupling.
How a dependent object gets its dependency object?
To get a dependency object, there are two options.
1. dependency injection mechanism
2. dependency lookup mechanism
In Dependency Injection(DI), the dependency object will
be injected to the dependent object by an external
entity called container.
In Dependency Lookup(DL), the dependent object should
contain the code for creating the dependency object, or
the dependent object should lookup for the dependency
object in the registry/cache.
In Spring framework, the Spring container injects the
dependency objects to the dependent objects. So, Spring
follows Dependency Injection.
Inversion of Control(IoC)?
IoC is a design principle which flips the normal flow
of an application.
IoC inverts the flow of control from the application
developer to the spring container/framework.
In a normal flow of an application, the application
developer has to do the below things.
1. Define the classes with the “logic”.
2. Instantiate the classes.
3. Assemble the dependencies required.
4. Manage the objects as long as they are needed.
5. destroy the object, if not needed.
In IoC, some responsibilities are transferred to the
Spring Framework.
A Developer has to define the classes with the
“logics”.
The Spring IoC container will do the below things.
1. Instantiation : creating the objects when they are
needed.
2. Assembling: injects the required dependencies for
an object.
3. Managing: Keeps the objects alive as long as they
are needed.
4. Destory : destroys the objects, when they are not
needed.
IoC is a “design pattern” and Spring uses Dependency
Injection mechanism to implement IoC principle.
Who are the Spring Containers?
Spring Framework has provided, two types of containers.
1. BeanFactory
2. ApplicationContext
BeanFactory and ApplicationContext are the interfaces
provided by spring framework.
The implementations of these interfaces contains the
logics for instantiation, assembling, managing and
destroying the objects.
BeanFactory is a basic container and ApplicationContext
is an advanced container with some additional features.
As a programmer/developer we should provide some
metadata of our classes to the spring container. So
that it can read and realizes what objects are required
in the application.
A developer has to use annotations or XML to provide
this metadata.
The Spring container reads the configuration,
understands what objects are required, then
instantiates them, injects the dependencies and makes
that object in a ready-to-use state.
The Spring container will store all these objects in
internal Bean cache and provides them when they are
required.
Types of dependency injections:
[Link] injection
[Link] injection
[Link] injection
In Constructor injection, the dependent class
defines a constructor and the spring container
injects the depedency object through that
constructor.
In Setter injection, the dependent class defines
a setter method and the spring container
injects the dependency through that setter
method.
In Field injection, the dependent class adds an
annotation @Autowired on the dependency
field, so that the spring container injects the
dependency object.
Ex1:
public class UserService {
PasswordEncoder pwdEncoder;
// constructor
public UserService(PasswordEncoder
pwdEncoder) {
[Link]=pwdEncoder;
}
}
UserService class : It is dependent class
PasswordEncoder class : It is dependency
class
UserService has defined a constructor for
injecting the dependency object. This is
constructor injection.
Ex2:
public class UserService {
PasswordEncoder pwdEncoder;
// setter method
public void
setPwdEncoder(PasswordEncoder pwdEncoder)
{
[Link]=pwdEncoder;
}
}
UserService class : It is dependent class
PasswordEncoder class : It is dependency
class
UserService has defined a setter method for
injecting the dependency object. This is setter
injection.
Ex3:
public class UserService {
@Autowired
PasswordEncoder pwdEncoder;
}
UserService class : It is dependent class
PasswordEncoder class : It is dependency
class
UserService has added @Autowired
annotation on the field. So, it is field injection.
How a spring configuration(xml) will be
written?
The filename could be [Link](ex:
[Link])
For example:
[Link]
-----------------
<beans>
<bean id=”userService”
class=”[Link]”>
<property name=”pwdEncoder”
ref=”pwder”/>
</bean>
<bean id=”pwder”
class=”[Link]”>
</bean>
</beans>
Maven tool
----------------------------------
what is Build process of a Java application?
A real-time Java application source code will be
available in a GitHub repository.
The build process of the project will start, once the
code is pulled from the GitHub repository.
1. add the required jars in classpath to compile the
source code.
2. compile the source code
3. add the required jars in classpath to compile and
run the test cases.
4. compile and execute the test cases.
5. If tests are passed, then package the application
into a jar/war file.
6. Deploy the jar/war file to a server.
If any defects/errors are identified while testing the
application on a server, the source code will be
modified and then it will be pushed to the GitHub
repository.
The above steps should be repeated to build a new
jar/war file to deploy it on a server.
Manually performing this build process is a time taken
and error-prone process. So to automate this build
process, a build tool is required.
The two popular build tools for Java are Maven and
Gradle.
A project folder structure in Maven:
Project parameters:
[Link]
[Link]
[Link]
A groupId is a unique id, used to identify a set of
projects developed by that group/company.
To make a groupId as unique, it is recommended to use
reverse domain name of the organization as groupId.
ex: [Link]
[Link]
artifactId is nothing but the project name, with which
you want to create a jar/war file of the project.
version is the version of the project.
[Link](project object model):
This file is used to define the dependencies of a
project.
The dependency means, saying that My project needs
the support of another project or library.
Ex:
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-context</artifactId>
<version>7.0.7</version>
</dependency>
When you add a depedency in [Link], maven will do
the following.
1. It will search for the library in the local
repository(C:\Users\Lenovo\.m2\repository).
2. If not exist, then Maven will search for the library
in the central repository, and then downloads it into
local repository.
3. Now maven adds the dependencies to the compile
classpath, and test classpath.
Maven project lifecycle stages:
1. Validate : Maven checks for project structure and
[Link] file
2. Compile: Maven compiles the source code
3. Test : Maven compiles and runs the test cases.
4. Package: Maven packages the project code into a
distributable format(jar/war)
5. Verify: Maven runs the integration tests and code
quality checks.
6. Install: Maven installs the packaged jar/war file into
local repository.
7. Deploy: Maven installs the packaged jar/war file into
remote repository.
8. Clean: Maven deletes all the files generated in the
previous build.
Spring HelloWorld application:
1) Start IntelliJ
2) File -> new -> Java project -> Enter Name:
HelloWorldApp -> location: D:\Workspaces\91-
SMWMS -> choose build system: Maven ->
Advanced Settings -> groupId: [Link]
artifactId:HelloWorldApp
create
3) open [Link] file and add the below dependencies
tag after the properties.
<dependencies>
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-context</artifactId>
<version>6.2.14</version>
</dependency>
</dependencies>
4) After configuring the above dependency, click on
Maven Sync icon , to sync the changes with
IntelliJ.
5) Delete [Link] file from [Link] package.
6) Now create two subpackages bean and main under
[Link] package.
7) Create a New Java class, HelloWorld under bean
package.
8) Create a new file under src/main/resources, with the
name [Link].
<beans
xmlns="[Link]
xmlns:xsi="[Link]
instance"
xsi:schemaLocation="[Link]
/beans
[Link]
[Link]">
<bean id = "helloWorld" class =
"[Link]">
</bean>
</beans>
9) Create a new Java class with Name: Main under
main package.
10) Run the Main class.
Setter injection example:
[Link]
package [Link];
// target class/dependent class
public class OrderService {
InventoryService inventoryService;
public void setInventoryService(InventoryService
inventoryService) {
[Link] = inventoryService;
}
public void placeOrder(String skuCode, int
requiredQuantity) {
boolean flag = [Link](skuCode,
requiredQuantity);
if(flag)
[Link]("Order placed successfully");
else
[Link]("Out of Stock, Please try
later...");
}
}
[Link]
package [Link];
import [Link];
// dependency class
public class InventoryService {
Map<String,Integer> stock = [Link]("oneplusce6", 8,
"iphone17", 5, "vivox13", 15);
public boolean isInStock(String skuCode, int
requiredQuantity) {
if ([Link](skuCode) && [Link](skuCode)
>= requiredQuantity) {
return true;
}
return false;
}
}
[Link]
<beans xmlns="[Link]
xmlns:xsi="[Link]
xsi:schemaLocation="[Link]
s
[Link]
<bean id="orderService"
class="[Link]">
<property name="inventoryService"
ref="inventoryService" />
</bean>
<bean id="inventoryService"
class="[Link]">
</bean>
</beans>
[Link]
package [Link];
import [Link];
import [Link];
import [Link];
public class Main {
public static void main(String[] args) {
// start the Spring Container
ApplicationContext ctx = new
ClassPathXmlApplicationContext("[Link]");
// get the OrderService bean
Object ob = [Link]("orderService");
OrderService orderService = (OrderService) ob;
//call the method
[Link]("iphone17", 10);
}
}
Constructor injection example:
[Link]
package [Link];
public class Kitchen {
private String foodItemName;
private String status;
public Kitchen(String foodItemName, String status) {
[Link] = foodItemName;
[Link] = status;
}
public String getFoodItemName() {
return foodItemName;
}
public void setFoodItemName(String foodItemName) {
[Link] = foodItemName;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
[Link] = status;
}
}
[Link]
package [Link];
public class Delivery {
private String deliveryStatus;
private String eta;
public Delivery(String deliveryStatus, String eta) {
[Link] = deliveryStatus;
[Link] = eta;
}
public String getDeliveryStatus() {
return deliveryStatus;
}
public void setDeliveryStatus(String deliveryStatus) {
[Link] = deliveryStatus;
}
public String getEta() {
return eta;
}
public void setEta(String eta) {
[Link] = eta;
}
}
[Link]
package [Link];
import [Link];
public class DeliveryStatus {
public Delivery findDeliveryStatus(String orderId) {
if ([Link]("123-456"))
return new Delivery("PICKED-UP", "12:10PM");
else if([Link]("456-321"))
return new Delivery("ENROUTE", "11:57AM");
else
return null;
}
}
[Link]
package [Link];
import [Link];
public class KitchenStatus {
public Kitchen findKitchenStatus(String orderId) {
if([Link]("123-456"))
return new Kitchen("Veg-Starter", "PREPARED");
else if([Link]("456-321"))
return new Kitchen("NonVegStarter", "PREPARING");
else
return null;
}
}
[Link]
package [Link];
import [Link];
import [Link];
public class OrderStatus {
KitchenStatus kitchenStatus;
DeliveryStatus deliveryStatus;
public OrderStatus(KitchenStatus kitchenStatus,
DeliveryStatus deliveryStatus) {
[Link] = kitchenStatus;
[Link] = deliveryStatus;
}
public void findOrderStatus(String orderId) {
Kitchen kitchen =
[Link](orderId);
Delivery delivery =
[Link](orderId);
if(kitchen != null && delivery != null) {
[Link]("order id : " + orderId);
[Link]("food item : " +
[Link]());
[Link]("food item status : " +
[Link]());
[Link]("delivery status : " +
[Link]());
[Link]("ETA : " + [Link]());
}
else {
[Link]("The orderid : " + orderId + "
is invalid!");
}
}
}
[Link]
<beans xmlns="[Link]
xmlns:xsi="[Link]
xsi:schemaLocation="[Link]
s
[Link]
<bean id = "orderStatus" class =
"[Link]">
<constructor-arg name = "kitchenStatus" ref =
"kitchenStatus" />
<constructor-arg name = "deliveryStatus" ref =
"deliveryStatus" />
</bean>
<bean id = "kitchenStatus" class =
"[Link]">
</bean>
<bean id = 'deliveryStatus' class =
"[Link]">
</bean>
</beans>
[Link]
package [Link];
import [Link];
import [Link];
import
[Link]
text;
public class Main {
public static void main(String[] args) {
// start the spring container
ApplicationContext ctx = new
ClassPathXmlApplicationContext("[Link]");
Object ob = [Link]("orderStatus");
OrderStatus orderStatus = (OrderStatus) ob;
[Link]("456-789");
}
}
What is Circular Dependency?