2
2
.
.
8
8
S
S
e
e
r
r
v
v
i
i
c
c
e
e
I
I
n
n
f
f
o
o
Following tutorials explain why and how to use Services (Service Layer).
Service is Class that implements business logic.
It is called by Controller and it uses Entities to do its work.
Final Application Schema
MyController
@Autowired
@Qualifier("implementation1")
MyServiceInterface myService;
MyServiceInterface
@Service("implementation1")
MyServiceImplementation1
@Service("implementation2")
MyServiceImplementation2
2
2
.
.
8
8
.
.
1
1
B
B
u
u
s
s
i
i
n
n
e
e
s
s
s
s
L
L
o
o
g
g
i
i
c
c
-
-
I
I
n
n
s
s
i
i
d
d
e
e
C
C
o
o
n
n
t
t
r
r
o
o
l
l
l
l
e
e
r
r
I
I
n
n
f
f
o
o
[
[
G
G
]
]
We will start by making Controller that doesn't use Service.
Instead business logic is implemented inside the Controller itself.
In our example business logic is to return "Hello" String.
Such approach is not ideal because each Class should do one thing and one thing only.
But in this case Controller does two things
accepts incoming HTTP Requests
implements business logic
This causes following problems
Application becomes harder to maintain and test since everything is in one Class
Controller becomes big and unreadable by having all of the business logic placed inside its end points.
To change business logic we need to change the Controller potentially introducing bugs which might
affect its main purpose of routing HTTP Requests
affect other parts of business logic if Controller becomes corrupted
Application Schema [Results]
Spring Boot Starters
GROUP
DEPENDENCY
DESCRIPTION
Web
Spring Web
Enables: @Controller, @RequestMapping, Tomcat Server
MyController
http://localhost:8080/Hello
Tomcat
Browser
P
P
r
r
o
o
c
c
e
e
d
d
u
u
r
r
e
e
Create Project: springboot_service_controller (add Spring Boot Starters from the table)
Create Package: controllers (inside main package)
Create Class: MyController.java (inside package controllers)
MyController.java
package com.ivoronline.springboot_service_controller.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MyController {
@ResponseBody
@RequestMapping("/Hello")
public String hello() {
//BUSINESS LOGIC
String result = "Hello from Controller";
//RETURN RESULT
return result;
}
}
R
R
e
e
s
s
u
u
l
l
t
t
s
s
http://localhost:8080/Hello
Application Properties
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2
2
.
.
8
8
.
.
2
2
B
B
u
u
s
s
i
i
n
n
e
e
s
s
s
s
L
L
o
o
g
g
i
i
c
c
-
-
I
I
n
n
s
s
i
i
d
d
e
e
S
S
e
e
r
r
v
v
i
i
c
c
e
e
I
I
n
n
f
f
o
o
[
[
G
G
]
]
The above problems can be solved by creating separate Service Class for each part of business logic.
That way we get multiple smaller more manageable Classes each focusing on a specific part of business logic.
With this approach
Controller now has a single task of routing incoming HTTP Requests to appropriate Service
to change business logic we don't need to change the Controller potentially introducing bugs in it
Application Schema [Results]
Spring Boot Starters
GROUP
DEPENDENCY
DESCRIPTION
Web
Spring Web
Enables @Controller and @RequestMapping. Includes Tomcat Server.
@Service
MyService
http://localhost:8080/Hello
Tomcat
hello()
Browser
MyController
P
P
r
r
o
o
c
c
e
e
d
d
u
u
r
r
e
e
Create Project: springboot_service (add Spring Boot Starters from the table)
Create Package: controllers (inside main package)
Create Class: MyController.java (inside package controllers)
Create Package: services (inside main package)
Create Class: MyService.java (inside package controllers)
MyService.java
package com.ivoronline.springboot_service.services;
import org.springframework.stereotype.Service;
@Service
public class MyService {
public String hello() {
return "Hello from Service";
}
}
MyController.java
package com.ivoronline.springboot_service.controllers;
import com.ivoronline.springboot_service.services.MyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MyController {
@Autowired MyService myService;
@ResponseBody
@RequestMapping("/Hello")
public String hello() {
//CALL SERVICE
String result = myService.hello();
//RETURN RESULT
return result;
}
}
R
R
e
e
s
s
u
u
l
l
t
t
s
s
http://localhost:8080/Hello
Application Structure
2
2
.
.
8
8
.
.
3
3
I
I
n
n
s
s
t
t
a
a
n
n
t
t
i
i
a
a
t
t
e
e
S
S
e
e
r
r
v
v
i
i
c
c
e
e
-
-
U
U
s
s
i
i
n
n
g
g
C
C
l
l
a
a
s
s
s
s
I
I
n
n
f
f
o
o
[
[
G
G
]
]
In this example we will instantiate MyService Class as Property inside MyController.
Application Schema [Results]
Spring Boot Starters
GROUP
DEPENDENCY
DESCRIPTION
Web
Spring Web
Enables: @Controller, @RequestMapping, Tomcat Server
MyService
http://localhost:8080/Hello
Tomcat
hello()
Browser
MyController
P
P
r
r
o
o
c
c
e
e
d
d
u
u
r
r
e
e
Create Project: springboot_service_class (add Spring Boot Starters from the table)
Create Package: controllers (inside main package)
Create Class: MyController.java (inside package controllers)
Create Package: services (inside main package)
Create Class: MyService.java (inside package controllers)
MyService.java
package com.ivoronline.springboot_service_class.services;
import org.springframework.stereotype.Service;
@Service
public class MyService {
public String hello() {
return "Hello from Service";
}
}
MyController.java
package com.ivoronline.springboot_service_class.controllers;
import com.ivoronline.springboot_service_class.services.MyService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MyController {
MyService myService = new MyService();
@ResponseBody
@RequestMapping("/Hello")
public String hello() {
//CALL SERVICE
String result = myService.hello();
//RETURN RESULT
return result;
}
}
R
R
e
e
s
s
u
u
l
l
t
t
s
s
http://localhost:8080/Hello
Application Structure
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2
2
.
.
8
8
.
.
4
4
I
I
n
n
s
s
t
t
a
a
n
n
t
t
i
i
a
a
t
t
e
e
S
S
e
e
r
r
v
v
i
i
c
c
e
e
-
-
U
U
s
s
i
i
n
n
g
g
C
C
l
l
a
a
s
s
s
s
-
-
@
@
A
A
u
u
t
t
o
o
w
w
i
i
r
r
e
e
d
d
I
I
n
n
f
f
o
o
[
[
G
G
]
]
Previous example can be simplified by using @Autowired to tell Spring to create Service Instance.
This way we don't need to manually create Service Instance inside the Controller's endpoint.
But with this approach we are tightly coupling Controller with specific Service implementation.
This means that if we want to use different Service Class that implements this part of business logic we would still need to
make changes to the Controller which increases our workload and potentially introduces bugs in it.
So a more elegant solution would be to use Service Interface inside the Controller.
Application Schema [Results]
Spring Boot Starters
GROUP
DEPENDENCY
DESCRIPTION
Web
Spring Web
Enables @Controller and @RequestMapping. Includes Tomcat Server.
MyService
http://localhost:8080/Hello
Tomcat
hello()
Browser
MyController
@Autowired
P
P
r
r
o
o
c
c
e
e
d
d
u
u
r
r
e
e
Create Project: springboot_service_class (add Spring Boot Starters from the table)
Create Package: controllers (inside main package)
Create Class: MyController.java (inside package controllers)
Create Package: services (inside main package)
Create Class: MyService.java (inside package controllers)
MyService.java
package com.ivoronline.springboot_service_class_autowired.services;
import org.springframework.stereotype.Service;
@Service
public class MyService {
public String hello() {
return "Hello from Service";
}
}
MyController.java
package com.ivoronline.springboot_service_class_autowired.controllers;
import com.ivoronline.springboot_service_class_autowired.services.MyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MyController {
@Autowired MyService myService;
@ResponseBody
@RequestMapping("/Hello")
public String hello() {
//CALL SERVICE
String result = myService.hello();
//RETURN RESULT
return result;
}
}
R
R
e
e
s
s
u
u
l
l
t
t
s
s
http://localhost:8080/Hello
Application Structure
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2
2
.
.
8
8
.
.
5
5
I
I
n
n
s
s
t
t
a
a
n
n
t
t
i
i
a
a
t
t
e
e
S
S
e
e
r
r
v
v
i
i
c
c
e
e
-
-
U
U
s
s
i
i
n
n
g
g
I
I
n
n
t
t
e
e
r
r
f
f
a
a
c
c
e
e
I
I
n
n
f
f
o
o
[
[
G
G
]
]
In this step we will introduce Service Interface to decouple Controller from specific Service implementation.
Inside Controller we will just reference this interface and not any specific implementation of it.
In other words Spring will create an Object from a Service Class that implements this Service Interface.
Since we will have only one Service Class that implements this Service Interface Spring will know which one to use.
Application Schema [Results]
Spring Boot Starters
GROUP
DEPENDENCY
DESCRIPTION
Web
Spring Web
Enables: @Controller, @RequestMapping, Tomcat Server
MyController
http://localhost:8080/Hello
hello()
MyServiceInterface
MyServiceImpl...
Browser
Tomcat
P
P
r
r
o
o
c
c
e
e
d
d
u
u
r
r
e
e
Create Project: springboot_service_interface (add Spring Boot Starters from the table)
Create Package: controllers (inside main package)
Create Class: MyController.java (inside package controllers)
Create Package: services (inside main package)
Create Class: MyServiceInterface.java (inside package controllers)
Create Class: MyServiceImplementation.java (inside package controllers)
MyServiceInterface.java
package com.ivoronline.springboot_service_interface.services;
public interface MyServiceInterface {
public String hello();
}
MyServiceImplementation.java
package com.ivoronline.springboot_service_interface.services;
import org.springframework.stereotype.Service;
@Service
public class MyServiceImplementation implements MyServiceInterface {
public String hello() {
return "Hello from Service";
}
}
MyController.java
package com.ivoronline.springboot_service_interface.controllers;
import com.ivoronline.springboot_service_interface.services.MyServiceImplementation;
import com.ivoronline.springboot_service_interface.services.MyServiceInterface;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MyController {
MyServiceInterface myService = new MyServiceImplementation();
@ResponseBody
@RequestMapping("/Hello")
public String hello() {
//CALL SERVICE
String result = myService.hello();
//RETURN RESULT
return result;
}
}
R
R
e
e
s
s
u
u
l
l
t
t
s
s
http://localhost:8080/Hello
Application Properties
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
2
2
.
.
8
8
.
.
6
6
I
I
n
n
s
s
t
t
a
a
n
n
t
t
i
i
a
a
t
t
e
e
S
S
e
e
r
r
v
v
i
i
c
c
e
e
-
-
U
U
s
s
i
i
n
n
g
g
I
I
n
n
t
t
e
e
r
r
f
f
a
a
c
c
e
e
-
-
@
@
A
A
u
u
t
t
o
o
w
w
i
i
r
r
e
e
d
d
I
I
n
n
f
f
o
o
[
[
G
G
]
]
In this step we will introduce Service Interface to decouple Controller from specific Service implementation.
Inside Controller we will just reference this interface and not any specific implementation of it.
In other words Spring will create and Object from a Service Class that implements this Service Interface.
Since we will have only one Service Class that implements this Service Interface Spring will know which one to use.
If there are multiple Classes that Implements the same Interface then you can use @Primary, @Qualifier or @Profile to
tell Spring from which Implementation to create instance.
Application Schema [Results]
Spring Boot Starters
GROUP
DEPENDENCY
DESCRIPTION
Web
Spring Web
Enables: @Controller, @RequestMapping, Tomcat Server
MyController
http://localhost:8080/Hello
hello()
MyServiceInterface
MyServiceImpl...
Browser
Tomcat
P
P
r
r
o
o
c
c
e
e
d
d
u
u
r
r
e
e
Create Project: springboot_service_interface_autowired (add Spring Boot Starters from the table)
Create Package: controllers (inside main package)
Create Class: MyController.java (inside package controllers)
Create Package: services (inside main package)
Create Class: MyServiceInterface.java (inside package controllers)
Create Class: MyServiceImplementation.java (inside package controllers)
MyServiceInterface.java
package com.ivoronline.springboot_service_interface_autowired.services;
public interface MyServiceInterface {
public String hello();
}
MyServiceImplementation.java
package com.ivoronline.springboot_service_interface_autowired.services;
import org.springframework.stereotype.Service;
@Service
public class MyServiceImplementation implements MyServiceInterface {
public String hello() {
return "Hello from Service";
}
}
MyController.java
package com.ivoronline.springboot_service_interface_autowired.controllers;
import com.ivoronline.springboot_service_interface_autowired.services.MyServiceInterface;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MyController {
@Autowired MyServiceInterface myService;
@ResponseBody
@RequestMapping("/Hello")
public String hello() {
//CALL SERVICE
String result = myService.hello();
//RETURN RESULT
return result;
}
}
R
R
e
e
s
s
u
u
l
l
t
t
s
s
http://localhost:8080/Hello
Application Structure
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>