The Service Layer
The @Service layer is where business logic lives — separated from the web layer so it is reusable, testable, and the natural home for orchestration and @Transactional boundaries.
Learn The Service Layer in our free Java course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Java course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Before You Start
You've built REST controllers and learned request mapping . This lesson shows where the logic those controllers call should actually live.
What You'll Learn
The Big Idea — The Kitchen Behind the Counter
💡 Analogy: If the controller is the waiter , the @Service is the kitchen . All the real work — combining ingredients, following the recipe, timing the dishes (your business rules and orchestration) — happens in the kitchen, out of sight of the dining room. The same kitchen can serve dine-in, takeaway, or catering (a controller, a CLI, a job) because it doesn't care how the order arrived.
Keeping the cooking out of the dining room is exactly what separation of concerns buys you.
1️⃣ Marking a Service with @Service
@Service is a stereotype of @Component that registers a bean and signals it holds business logic . The logic inside is completely free of HTTP concerns.
2️⃣ The Controller Delegates to the Service
The controller injects the service and simply delegates : parse input, call the service, return the result. All the rules stay in one reusable, testable place.
3️⃣ Orchestration & Transactions
A service can coordinate several collaborators to perform one use case. Wrapping that method in @Transactional makes the multi-step operation atomic — commit on success, roll back on failure.
4️⃣ Reuse Beyond the Web
Because the logic is in a service, the same code is callable from anywhere — here we use it via a controller and directly, with no HTTP involved.
🧠 Quick Recall
Answer: No — it's a specialised @Component. The difference is semantic: it documents the business layer.
Answer: in the service layer — not in controllers (web concerns only).
Answer: on service methods that coordinate a unit of work across repositories.
Common Errors
- ❌ Logic in the controller. Not reusable or easily tested. Fix: move it into a @Service.
- ❌ @Transactional on controllers. Couples transactions to HTTP. Fix: put it on service methods.
- ❌ Anaemic services that just forward calls. Add no value. Fix: let services own real rules/orchestration.
- ❌ Circular service dependencies. A↔B. Fix: extract a third component or rethink boundaries.
- ❌ Web types in the service. e.g. HttpServletRequest. Fix: keep services HTTP-agnostic.
Pro Tips
- 💡 Keep services HTTP-agnostic so they're reusable from jobs and CLIs.
- 💡 Use the right stereotype — @Service for logic, @Repository for data — to express intent.
- 💡 Put @Transactional on the orchestrating method , the true unit of work.
- 💡 Program to interfaces so services are easy to fake in tests.
📋 Quick Reference
Concept
Syntax / idea
Note
service bean
@Service
Business layer
stereotype of
@Component
Semantic role
controller role
delegate to service
Stay thin
service holds
rules + orchestration
No HTTP
transactions
@Transactional
On service methods
benefit
reusable + testable
Separation of concerns
📚 Resources / Keep Learning
- 📘 Classpath Scanning & Stereotypes — Spring docs
- 📗 Declarative Transaction Management — Spring docs
- 📗 Managing Transactions — spring.io guide
❓ Frequently Asked Questions
🎉 Lesson Complete!
You now know what the @Service layer is for, why it's a semantic @Component, why controllers should delegate to it, how services orchestrate other beans, and where @Transactional boundaries belong.
Next up: Repositories & @Repository — the persistence boundary your services depend on.
Practice quiz
What does the @Service annotation mark?
- A bean holding business logic in the service layer
- A web endpoint
- A database table
- A configuration file
Answer: A bean holding business logic in the service layer. @Service is a stereotype of @Component that marks a bean as part of the service (business logic) layer.
Is @Service functionally different from @Component to the container?
- Yes, it changes scope
- No — it's a specialised @Component conveying intent
- Yes, it disables injection
- Yes, it makes the bean lazy
Answer: No — it's a specialised @Component conveying intent. Technically @Service is just @Component with a clearer semantic role; both register the class as a bean.
What belongs in the service layer?
- HTTP status mapping
- URL routing
- Business rules, validation and orchestration
- JSON serialisation
Answer: Business rules, validation and orchestration. The service layer holds business logic: rules, calculations, validation and coordination across repositories.
How does a controller use a service?
- By extending it
- By injecting it (constructor) and delegating to it
- By creating it with new each call
- By importing application.properties
Answer: By injecting it (constructor) and delegating to it. Controllers inject the service via the constructor and delegate business operations to it.
Why separate the service layer from controllers?
- It runs faster on the GPU
- Separation of concerns: reusable, testable logic independent of HTTP
- Java requires it
- To reduce the number of classes
Answer: Separation of concerns: reusable, testable logic independent of HTTP. Keeping logic out of controllers makes it reusable (jobs, other controllers) and testable without the web layer.
Where is @Transactional most commonly placed?
- On controllers
- On records
- On the main class
- On service-layer methods that coordinate a unit of work
Answer: On service-layer methods that coordinate a unit of work. Transaction boundaries usually wrap service methods, where a business operation spans one or more repository calls.
A well-designed service typically depends on...
- the HttpServletResponse
- one or more repositories (injected)
- the view templates
- the build file
Answer: one or more repositories (injected). Services orchestrate persistence by injecting and calling repositories, keeping data access behind that boundary.
Which layer should NOT contain business rules?
- The service layer
- The controller (web) layer
- A domain service
- A use-case class
Answer: The controller (web) layer. The controller layer handles web concerns only; business rules belong in the service layer.
Making services depend on interfaces helps mainly with...
- compilation speed
- smaller jars
- swapping implementations and testing with fakes
- JSON formatting
Answer: swapping implementations and testing with fakes. Coding to interfaces lets you substitute implementations and inject fakes/mocks in tests.
A thin controller calling a rich service is an example of...
- tight coupling
- a memory leak
- premature optimisation
- separation of concerns
Answer: separation of concerns. Delegating logic to the service keeps each layer focused — a clean separation of concerns.
Continue this course
- Previous: Request Mapping & Parameters
- Next: Repositories & @Repository