A lightweight Java web server with a built-in IoC framework that leverages reflection, custom annotations, and meta-object protocols to discover and load REST controllers automatically β all powered by raw Java sockets with zero external dependencies.
MicroSpringBoot starting with auto-discovered routes and configuration banner
Dark-themed API Explorer served from the /webroot static files directory
GET /hello returning "Hello World!"
GET /greeting?name=Pedro returning a personalized JSON greeting
GET /pi returning the value of Math.PI
GET /time returning the current server timestamp
All 124 unit tests passing with BUILD SUCCESS
Server running on an AWS EC2 instance accessible via public IP with full step-to-step
| Feature | Description |
|---|---|
| π·οΈ @RestController | Marks classes as REST components for automatic IoC discovery |
| π @GetMapping | Maps HTTP GET requests to handler methods with path binding |
| π @RequestParam | Extracts query parameters with default value support |
| π‘ Classpath Scanning | Automatically discovers all annotated controllers at startup |
| π§ CLI Controller Loading | Load specific controllers via command-line arguments |
| π Static File Serving | Serves HTML, CSS, JS, PNG, JPG, GIF, SVG, ICO, JSON from classpath |
| β‘ Zero Dependencies | Built with pure Java sockets β no Spring, no Jetty, no external libs |
| πͺ Java Reflection | Runtime method invocation, annotation processing, meta-object protocol |
| π§ͺ 124 Unit Tests | Comprehensive test coverage across all framework components |
| π§© IoC Pattern | Inversion of Control with automatic bean instantiation |
These instructions will give you a copy of the project up and running on your local machine for development and testing purposes.
| Requirement | Description |
|---|---|
| Java 17+ | JDK for compiling and running |
| Maven 3.9+ | Build automation tool |
| Git | Version control |
-
Clone the repository
git clone https://github.com/AnderssonProgramming/ioc-application-server.git cd ioc-application-server -
Build the project
mvn clean compile
-
Run the tests
mvn test -
Start the server (auto-scan mode)
mvn exec:java
-
Start the server (CLI mode β specific controller)
java -cp target/classes co.edu.escuelaing.reflexionlab.MicroSpringBoot co.edu.escuelaing.reflexionlab.demo.HelloController
-
Open your browser and test
URL Description http://localhost:8080/ Static web page (API Explorer) http://localhost:8080/hello Hello World greeting http://localhost:8080/greeting?name=Pedro Personalized greeting with @RequestParam http://localhost:8080/pi Value of Math.PI http://localhost:8080/square?n=7 Square of a number http://localhost:8080/time Current server time
This project builds a web application server (similar to Apache) in Java, enhanced with an IoC (Inversion of Control) framework that uses Java reflection and custom annotations to automatically discover and load REST controllers. The architecture is inspired by Spring Boot, demonstrating how frameworks leverage meta-object protocols for enterprise application development.
IoC is a design pattern where the flow of a program is inverted β instead of the programmer controlling the flow, a framework takes control:
π Annotated POJO β π Component Scanner β πͺ Reflection β π Route Registry β β‘ Request Handler
- Component Scanning β The framework scans the classpath for
@RestControllerclasses - Reflection β Discovers
@GetMappingmethods and@RequestParamparameters at runtime - Bean Instantiation β Creates controller instances (POJOs) automatically
- Route Registration β Maps URI paths to handler methods
- Request Handling β Resolves parameters and invokes methods via reflection
@RestController β "I am a component, discover me!"
@GetMapping("/path") β "Map GET /path to this method"
@RequestParam β "Bind this query parameter to my argument"
| Component | Technology | Why? |
|---|---|---|
| Language | Java 17 | Modern features, lambda support, reflection API |
| Networking | Raw Sockets (java.net) | Deep understanding of HTTP protocol |
| IoC | Custom Annotations + Reflection | Demonstrates meta-object protocol concepts |
| Build | Maven | Industry-standard Java build tool |
| Testing | JUnit 4 | Reliable, widely-adopted test framework |
| Dependencies | None (runtime) | Minimal footprint, educational value |
By studying this project, you will understand:
- β
How to create custom annotations (
@RestController,@GetMapping,@RequestParam) - β How Java reflection works (meta-object protocol, runtime introspection)
- β How IoC containers discover and instantiate beans (classpath scanning)
- β How HTTP protocol works at the socket level
- β How to parse HTTP requests (method, URI, query parameters, headers)
- β How to implement a routing system with reflection-based dispatch
- β How to serve static files with proper MIME type detection
- β The architecture and design of web frameworks like Spring Boot
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β HTTP Client (Browser) β
βββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β HTTP Request
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β MicroSpringBoot (Socket Listener) β
β Listens on port 8080 for connections β
βββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
ββββββββββββββ΄βββββββββββββ
β Startup: IoC Container β
β β
β 1. ComponentScanner β
β scans classpath β
β 2. Finds @RestControllerβ
β 3. Instantiates POJOs β
β 4. Registers @GetMappingβ
β routes via Reflectionβ
ββββββββββββββ¬βββββββββββββ
β Parse Request
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β HttpRequest Parser β
β Extracts: method, path, query params, headers β
βββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β Route Decision
βΌ
βββββββββββββ΄ββββββββββββ
βΌ βΌ
ββββββββββββββββββββ ββββββββββββββββββββββββ
β REST Route β β Static File Request β
β (RouteRegistry) β β (*.html, *.css, ...) β
β β β β
β RequestHandler β β StaticFileHandler β
β resolves params β β reads from classpathβ
β invokes method β β /webroot directory β
β via Reflection β β β
ββββββββββ¬ββββββββββ ββββββββββββ¬ββββββββββββ
β β
βΌ βΌ
ββββββββββββββββββββ ββββββββββββββββββββββββ
β @GetMapping β β File Bytes + β
β Method invoked β β MIME Content-Type β
β @RequestParam β β Detection β
β resolved β β β
ββββββββββ¬ββββββββββ ββββββββββββ¬ββββββββββββ
β β
ββββββββββββββ¬ββββββββββββ
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β HttpResponse Builder β
β Status line + Headers + Body β Output Stream β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
- Client sends an HTTP request to
localhost:8080 - MicroSpringBoot accepts the socket connection and reads the raw HTTP request
- HttpRequest Parser extracts the method, URI, query string, and headers
- Router decides:
- If path matches a registered
@GetMappingroute β delegate to RequestHandler - Otherwise β delegate to StaticFileHandler (static files)
- If path matches a registered
- RequestHandler resolves
@RequestParamannotations and invokes the method via reflection - HttpResponse Builder sends proper HTTP response with headers back to client
βββββββββββββββββββββββ
β Application β
β Startup β
ββββββββββββ¬βββββββββββ
β
ββββββββββββΌβββββββββββ
β ComponentScanner β
β scan("package") β
ββββββββββββ¬βββββββββββ
β finds .class files
ββββββββββββΌβββββββββββ
β Check: has β
β @RestController? β
ββββββββββββ¬βββββββββββ
β yes
ββββββββββββΌβββββββββββ
β Instantiate POJO β
β (newInstance()) β
ββββββββββββ¬βββββββββββ
β
ββββββββββββΌβββββββββββ
β Scan methods for β
β @GetMapping β
ββββββββββββ¬βββββββββββ
β
ββββββββββββΌβββββββββββ
β Register route in β
β RouteRegistry β
βββββββββββββββββββββββ
ioc-application-server/
βββ π README.md # Project documentation
βββ π AWS_DEPLOYMENT_GUIDE.md # Step-by-step AWS deployment guide
βββ π LICENSE # MIT License
βββ π pom.xml # Maven build configuration
βββ π .gitignore # Git ignore rules
βββ π images/ # Screenshots for README
βββ π src/
β βββ π main/
β β βββ π java/co/edu/escuelaing/reflexionlab/
β β β βββ π· MicroSpringBoot.java # Main server: IoC container + HTTP server
β β β βββ π annotations/
β β β β βββ π·οΈ RestController.java # @RestController β component marker
β β β β βββ π·οΈ GetMapping.java # @GetMapping β route binding
β β β β βββ π·οΈ RequestParam.java # @RequestParam β query parameter binding
β β β βββ π server/
β β β β βββ π· HttpRequest.java # HTTP request parser
β β β β βββ π· HttpResponse.java # HTTP response builder (fluent API)
β β β β βββ π· StaticFileHandler.java # Static file serving + MIME detection
β β β βββ π ioc/
β β β β βββ π· ComponentScanner.java # Classpath scanner for @RestController
β β β β βββ π· RouteRegistry.java # Route storage and lookup
β β β β βββ π· RequestHandler.java # Reflection-based method invoker
β β β βββ π demo/
β β β βββ π· HelloController.java # GET / and /hello
β β β βββ π· GreetingController.java # GET /greeting with @RequestParam
β β β βββ π· MathController.java # GET /pi, /square, /time
β β βββ π resources/
β β βββ π webroot/ # Static web files
β β βββ π index.html # API Explorer page
β β βββ π style.css # Dark theme stylesheet
β β βββ π app.js # Client-side API caller
β βββ π test/
β βββ π java/co/edu/escuelaing/reflexionlab/
β βββ π§ͺ MicroSpringBootTest.java # 13 integration tests
β βββ π annotations/
β β βββ π§ͺ AnnotationsTest.java # 15 annotation contract tests
β βββ π ioc/
β β βββ π§ͺ ComponentScannerTest.java # 10 classpath scanning tests
β β βββ π§ͺ RequestHandlerTest.java # 9 reflection invocation tests
β β βββ π§ͺ RouteRegistryTest.java # 14 route management tests
β βββ π server/
β βββ π§ͺ HttpRequestTest.java # 20 request parsing tests
β βββ π§ͺ HttpResponseTest.java # 17 response building tests
β βββ π§ͺ StaticFileHandlerTest.java # 26 static file tests
Marks a class as a REST component for automatic IoC discovery:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface RestController { }Maps HTTP GET requests to handler methods:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface GetMapping {
String value();
}Binds query parameters to method arguments with default value support:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface RequestParam {
String value();
String defaultValue() default "";
}Scans the classpath for @RestController annotated classes using Java reflection:
ComponentScanner scanner = new ComponentScanner();
List<Class<?>> controllers = scanner.scan("co.edu.escuelaing.reflexionlab.demo");
// Finds: HelloController, GreetingController, MathControllerResolves @RequestParam annotations and invokes controller methods via reflection:
// Incoming request: GET /greeting?name=Pedro
// β Resolves @RequestParam(value="name", defaultValue="World")
// β Invokes: greetingController.greeting("Pedro")
// β Returns: {"id": 1, "content": "Hello, Pedro!"}Parses raw HTTP requests into structured objects:
HttpRequest req = new HttpRequest("GET /greeting?name=Pedro HTTP/1.1\r\n...");
req.getMethod(); // "GET"
req.getPath(); // "/greeting"
req.getQueryParam("name"); // "Pedro"Serves files from the classpath with automatic MIME type detection:
| Extension | MIME Type |
|---|---|
.html, .htm |
text/html |
.css |
text/css |
.js |
application/javascript |
.json |
application/json |
.png |
image/png |
.jpg, .jpeg |
image/jpeg |
.gif |
image/gif |
.svg |
image/svg+xml |
.ico |
image/x-icon |
The main server class providing two modes of operation:
// Mode 1: Auto-scan (discovers all @RestController classes)
MicroSpringBoot server = new MicroSpringBoot();
server.scanComponents("co.edu.escuelaing.reflexionlab");
server.start();
// Mode 2: CLI (load specific controller)
// java -cp target/classes co.edu.escuelaing.reflexionlab.MicroSpringBoot \
// co.edu.escuelaing.reflexionlab.demo.HelloController@RestController
public class GreetingController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
@GetMapping("/greeting")
public String greeting(@RequestParam(value = "name", defaultValue = "World") String name) {
return String.format("{\"id\": %d, \"content\": \"%s\"}",
counter.incrementAndGet(), String.format(template, name));
}
}| URL | Response |
|---|---|
http://localhost:8080/ |
Static API Explorer page |
http://localhost:8080/hello |
Hello World! |
http://localhost:8080/greeting?name=Pedro |
{"id": 1, "content": "Hello, Pedro!"} |
http://localhost:8080/pi |
3.141592653589793 |
http://localhost:8080/square?n=7 |
49 |
http://localhost:8080/time |
2026-03-05 10:30:00 |
The project includes 124 unit tests covering all framework components:
| Test Class | Tests | Coverage Areas |
|---|---|---|
HttpRequestTest |
20 | Query params, URL decoding, headers, immutability |
HttpResponseTest |
17 | Status codes, fluent API, build output, headers |
StaticFileHandlerTest |
26 | MIME types, file detection, path handling |
RouteRegistryTest |
14 | Route CRUD, path normalization, immutability |
RequestHandlerTest |
9 | Route dispatch, @RequestParam resolution, defaults |
ComponentScannerTest |
10 | Classpath scanning, controller loading, validation |
AnnotationsTest |
15 | Retention policies, targets, annotation contracts |
MicroSpringBootTest |
13 | Integration tests, endpoints, scanning, static files |
mvn testExpected output:
[INFO] Tests run: 124, Failures: 0, Errors: 0, Skipped: 0
[INFO] BUILD SUCCESS
This server has been deployed on AWS EC2. For a complete step-by-step guide, see:
Quick summary:
- Launch an EC2 instance (Amazon Linux 2023 / Ubuntu)
- Install Java 17 and Maven
- Clone the repository and build
- Run the server on the EC2 instance
- Configure Security Group to allow inbound traffic on port 8080
| Technology | Purpose |
|---|---|
| Java 17 | Programming language with reflection and lambda support |
| Maven | Build automation and dependency management |
| JUnit 4 | Unit testing framework |
| Java Sockets | Raw TCP networking for HTTP server |
| Java Reflection API | Runtime introspection and method invocation |
| AWS EC2 | Cloud deployment |
The framework uses Java's reflection API as a meta-object protocol, providing programmatic access to language constructs (classes, methods, parameters, annotations) at runtime.
The framework follows the Hollywood Principle β "Don't call us, we'll call you." Developers define POJOs with annotations, and the framework takes control of:
- Component discovery (
@RestController) - Route registration (
@GetMapping) - Parameter binding (
@RequestParam) - Method invocation (via reflection)
Java reflection enables the framework to:
- Scan the classpath for annotated classes
- Instantiate controller objects dynamically
- Discover and invoke handler methods at runtime
- Resolve method parameter annotations for query binding
Andersson David SΓ‘nchez MΓ©ndez
This project is licensed under the MIT License - see the LICENSE file for details.
- Luis Daniel Benavides Navarro β Professor, course on Application Server Architectures, Meta-Object Protocols, IoC Pattern, and Reflection
- Escuela Colombiana de IngenierΓa Julio Garavito β AREP Course
- Java documentation team β Comprehensive reflection and networking tutorials
- Spring Boot β Inspiration for the annotation-based controller architecture
