Backend Development 8 min read

Building a Mini Spring MVC Framework from Scratch Using Pure JDK

This tutorial walks through creating a miniature Spring MVC framework using only the JDK, covering custom annotations, package scanning, component instantiation, dependency injection, URL mapping, and a custom DispatcherServlet, with complete code structure and runtime demonstration.

Java Captain
Java Captain
Java Captain
Building a Mini Spring MVC Framework from Scratch Using Pure JDK

Preparation

I will write a mini version of Spring MVC, starting from a clean web project without importing Spring, implementing everything with pure JDK.

Project structure is shown below:

Project code structure

About Custom Annotations

JDK provides several meta‑annotations such as @Documented, @Target, and @Retention, which are used to define custom annotations that mimic Spring MVC’s @Controller, @Qualifier, @RequestMapping, etc.

@Documented: JavaDoc documentation

@Target: indicates where the annotation can be applied (class, field, method, ...)

@Retention: defines the annotation’s lifecycle; for custom annotations we usually need runtime retention.

Below are the custom annotations used in this project:

Simulated @Controller annotation

@Qualifier for dependency injection

@RequestMapping for URL handling

Dao layer annotation

Service layer annotation

Implement Core Controller: DispatcherServlet

In Spring MVC, DispatcherServlet is the core component; it is essentially a subclass of HttpServlet. Our custom DispatcherServlet therefore extends HttpServlet.

pom.xml (dependency for servlet):

Servlet dependency

Definition of DispatcherServlet (shown as an image):

DispatcherServlet

@WebServlet is an annotation‑based way to declare a servlet, introduced in Servlet 3.0, replacing the old web.xml configuration.

We pass the base‑package to scan as an initialization parameter, avoiding XML configuration.

init Initialization Process

init()

During init we perform four main steps:

Scan the base package to collect class information (A).

For @Controller, @Service, @Repository annotations, obtain their names and instantiate the classes, building a name‑to‑instance map (B).

Inspect fields for @Qualifier and perform dependency injection.

Scan @RequestMapping annotations to build URL‑to‑method mappings (C).

Scanning Base Package

Scanning base package

The package name uses dot notation (X.Y.Z) while URLs use slash notation (X/Y/Z); conversion is required.

Instantiation

Instantiation

This step creates instances of classes annotated with our custom annotations and registers them by name.

Dependency Injection

Dependency injection

This mimics Spring IoC by injecting required dependencies into fields marked with @Qualifier.

URL Mapping Handling

URL mapping handling

The extracted URL is mapped to the corresponding controller method.

doGet / doPost

doGet/doPost

In doPost we simply extract the URL, look up the mapped method, and invoke it via reflection.

Run It!

Controller Layer

UserController

Service Layer

UserService

UserServiceImpl

Dao Layer

UserDao

UserDaoImpl

Run Result

Result

OK, the mini Spring MVC framework is now complete.

For reference, the XML configuration used for component scanning is:

<context:component-scan base-package="com.zfz.myspringmvc">
</context:component-scan>
backendJavaWeb DevelopmentSpring MVCDispatcherServletcustom annotations
Java Captain
Written by

Java Captain

Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.