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.
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>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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.