Spring Boot Learning Roadmap: From Intermediate to Employable in 90 Days
Purpose
I wasted 6 months before my first Spring Boot job. I jumped between microservices, Kafka, Kubernetes — stuff I never needed on day one. I should have focused on the core 20% that gets you 80% of the way.
This post is the roadmap I wish I had. Three phases, 30 days each. By day 90, you should be ready to apply and pass technical interviews.
The Big Mistake I Made
When I started learning Spring Boot, I tried to learn everything at once:
What I tried: What I should have done:├── Spring Cloud ├── JPA + REST├── Kafka ├── Spring Security basics├── Kubernetes ├── Testing (unit + integration)├── Microservices patterns ├── Redis (caching only)└── Event sourcing └── Docker (just enough to deploy)All that advanced stuff matters later. But for the first job, nobody asks you to design an event-driven microservices mesh. They want to know: can you build a CRUD API, secure it, test it, and deploy it?
The 90-Day Plan Overview
Phase 1: Project Core → Days 1-30 → JPA, REST, Security, TestingPhase 2: Production → Days 31-60 → Redis, Scheduling, Docker, DeployPhase 3: Job Prep → Days 61-90 → Swagger, Architecture review, Mock interviews, ApplyEach phase builds on the previous one. By the end of Phase 1, you have a working API. By the end of Phase 2, it’s deployable. By the end of Phase 3, you can talk about it in an interview.

Phase 1: Project Core (Days 1-30)
This phase is about building a single, working Spring Boot application with a database.
Week 1: Project Setup and JPA
- Generate a project with Spring Initializr
- Add Spring Web, Spring Data JPA, PostgreSQL driver, Lombok
- Create 2-3 entities with relationships
- Write repository methods using
@Query
Week 2: REST API
- Build CRUD endpoints for your entities
- Use
@RestController,@Service,@Repositorylayers - Handle exceptions with
@ControllerAdvice - Validate input with
@Valid
Week 3: Spring Security
- Add Spring Security dependency
- Implement JWT-based authentication
- Configure role-based access control
- Test all endpoints with different roles
Week 4: Testing
- Write unit tests with JUnit 5 and Mockito
- Write integration tests with
@SpringBootTest - Use
@DataJpaTestfor repository tests - Mock external calls with Mockito
Deliverable: A working blog API or todo app with JWT auth, tested endpoints, and a PostgreSQL database.
One rule I set for myself: no AI coding assistants for the first 30 days. Every line typed manually. Every error debugged alone. This builds real understanding.
Phase 2: Production Polish (Days 31-60)
Now you make your API production-ready.
Week 5: Caching with Redis
- Run Redis via Docker
- Add
@Cacheable,@CacheEvictannotations - Cache frequently queried data
- Handle cache invalidation
Week 6: Scheduling and Async
- Use
@Scheduledfor periodic tasks - Use
@Asyncfor long-running operations - Configure thread pools
Week 7: Dockerize the App
- Write a Dockerfile for your Spring Boot app
- Write a
docker-compose.ymlwith your app + PostgreSQL + Redis - Test the full stack locally with Docker Compose
Week 8: Deploy to a Server
- Set up a VPS (DigitalOcean, Linode, or Hetzner)
- Deploy via Docker Compose
- Set up Nginx reverse proxy
- Add HTTPS with Certbot
Deliverable: Your API runs on a real server, accessible via HTTPS, with caching and scheduled tasks.

Phase 3: Job Prep (Days 61-90)
The technical part is done. Now you need to pass interviews.
Week 9: API Documentation
- Add Springdoc OpenAPI (Swagger UI)
- Write meaningful API descriptions
- Add request/response examples
Week 10: Architecture Deep Dive
- Review your own code from Phase 1
- Understand why you made each decision
- Study common interview topics: DI, AOP, transaction propagation, isolation levels
Week 11: Mock Interviews
- Record yourself explaining your project
- Practice answering “Why did you choose X instead of Y?”
- Prepare for system design questions at your level (not senior architect)
Week 12: Apply
- Polish your GitHub README
- Update your resume with the project
- Apply to 5-10 positions per week
- Tailor each application
Deliverable: Resume with a live project, Swagger docs, and interview-ready explanations.
Anti-Pattern vs Pattern: JWT Filter Example
Here is something I got wrong many times — how to write a JWT filter. The anti-pattern is common among beginners.
Anti-Pattern: Spaghetti Filter
@Componentpublic class JwtFilter extends OncePerRequestFilter {
// mixing concerns: parsing, validation, and auth logic all here @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
String token = request.getHeader("Authorization"); if (token != null && token.startsWith("Bearer ")) { String jwt = token.substring(7); try { // parsing JWT inline Claims claims = Jwts.parser() .setSigningKey("my-secret-key".getBytes()) .parseClaimsJws(jwt) .getBody(); String username = claims.getSubject(); // setting SecurityContext inline UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken( username, null, List.of() ); SecurityContextHolder.getContext().setAuthentication(auth); } catch (Exception e) { // swallow or rethrow — unclear } } chain.doFilter(request, response); }}The problem: everything is in one method. Parsing, validation, context setup — no separation. If you change your JWT library, you rewrite the filter. If the token is expired, the error handling is vague.
Pattern: Clean Separation
@Componentpublic class JwtTokenProvider {
private final String secretKey;
public JwtTokenProvider(@Value("${jwt.secret}") String secretKey) { this.secretKey = secretKey; }
public String getUsernameFromToken(String token) { return Jwts.parser() .setSigningKey(secretKey.getBytes()) .parseClaimsJws(token) .getBody() .getSubject(); }
public boolean validateToken(String token) { try { Jwts.parser().setSigningKey(secretKey.getBytes()) .parseClaimsJws(token); return true; } catch (JwtException | IllegalArgumentException e) { return false; } }}@Component@RequiredArgsConstructorpublic class JwtFilter extends OncePerRequestFilter {
private final JwtTokenProvider tokenProvider;
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
String token = resolveToken(request); if (token != null && tokenProvider.validateToken(token)) { String username = tokenProvider.getUsernameFromToken(token); setSecurityContext(username); } chain.doFilter(request, response); }
private String resolveToken(HttpServletRequest request) { String bearer = request.getHeader("Authorization"); if (bearer != null && bearer.startsWith("Bearer ")) { return bearer.substring(7); } return null; }
private void setSecurityContext(String username) { UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken( username, null, List.of() ); SecurityContextHolder.getContext().setAuthentication(auth); }}The pattern separates concerns: token provider handles parsing and validation, filter handles HTTP concerns. Each class has one reason to change.
Why the 90-Day Approach Works
I learned this the hard way — trying to study everything makes you learn nothing. The 90-day plan forces constraint:
- Phase 1 locks in the fundamentals before you touch advanced topics. You can’t build on a shaky foundation.
- Phase 2 gives you real-world experience. Local code is different from running code. Caching, deployment, HTTPS — these are what employers actually pay for.
- Phase 3 shifts you from learner to candidate. The last month is purely about packaging yourself for the job market.
The 30-day-per-phase cadence also creates urgency. You can’t spend two weeks tweaking your Dockerfile. You ship it and move on.
The Week-by-Week Checklist
Week 1 [] Generate Spring Boot project with JPAWeek 1 [] Create entities and repositoriesWeek 2 [] Build CRUD REST endpointsWeek 2 [] Add exception handling and validationWeek 3 [] Implement JWT authenticationWeek 3 [] Add role-based access controlWeek 4 [] Write unit tests for servicesWeek 4 [] Write integration tests for controllersWeek 5 [] Add Redis cachingWeek 5 [] Test cache behaviorWeek 6 [] Add scheduled tasksWeek 6 [] Add async methodsWeek 7 [] Dockerize the applicationWeek 7 [] Set up Docker Compose (app + DB + Redis)Week 8 [] Deploy to a VPSWeek 8 [] Set up Nginx and HTTPSWeek 9 [] Add Swagger documentationWeek 10 [] Review architecture decisionsWeek 11 [] Practice mock interviewsWeek 12 [] Apply to jobsPrint this, put it on your wall, check each box before moving on.
Summary
In this post, I laid out a 90-day Spring Boot roadmap from intermediate to job-ready. Three phases — project core, production polish, job prep — each with weekly deliverables. The key point is that you don’t need to learn everything before your first job. You just need to build one solid API, deploy it, and be able to explain it.
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments