Skip to content

Commit 1b04825

Browse files
author
gabriele.sisinna
committed
Add structured learning documentation
1 parent eb5e688 commit 1b04825

8 files changed

Lines changed: 866 additions & 5 deletions

File tree

README.md

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
This project is built so you can learn, test, and modify small examples instead of reading a large codebase.
44

5+
Full repo learning notes are in [docs/README.md](./docs/README.md).
6+
57
## What this repo teaches
68

79
### Plain Java
@@ -15,6 +17,10 @@ This project is built so you can learn, test, and modify small examples instead
1517
- exceptions
1618
- packages
1719
- annotations
20+
- interfaces
21+
- inheritance and polymorphism
22+
- generics
23+
- streams and lambdas
1824

1925
### Spring Boot
2026

@@ -24,16 +30,25 @@ This project is built so you can learn, test, and modify small examples instead
2430
- request/response model
2531
- Swagger UI
2632
- OpenAPI YAML
33+
- validation
34+
- JPA + H2 persistence
35+
- basic authentication with Spring Security
36+
- unit, repository, and integration tests
2737

2838
## Start here
2939

3040
Read these files in order:
3141

3242
1. `src/main/java/com/example/demo/basics/model/Student.java`
3343
2. `src/test/java/com/example/demo/basics/model/StudentTest.java`
34-
3. `src/main/java/com/example/demo/spring/service/StudentService.java`
35-
4. `src/main/java/com/example/demo/spring/controller/StudentController.java`
36-
5. `src/test/java/com/example/demo/spring/controller/StudentControllerTest.java`
44+
3. `src/main/java/com/example/demo/basics/interfaces/Notifier.java`
45+
4. `src/main/java/com/example/demo/basics/inheritance/LearningStudent.java`
46+
5. `src/main/java/com/example/demo/basics/generics/Box.java`
47+
6. `src/main/java/com/example/demo/basics/streams/StudentAnalytics.java`
48+
7. `src/main/java/com/example/demo/spring/service/StudentService.java`
49+
8. `src/main/java/com/example/demo/spring/persistence/service/CourseService.java`
50+
9. `src/main/java/com/example/demo/spring/persistence/controller/CourseController.java`
51+
10. `src/test/java/com/example/demo/spring/persistence/controller/CourseControllerIntegrationTest.java`
3752

3853
## Package guide
3954

@@ -43,6 +58,14 @@ Read these files in order:
4358
- custom exception example
4459
- `com.example.demo.basics.model`
4560
- plain Java class with fields, constructors, methods, `if`, `for`, `List`, and `Map`
61+
- `com.example.demo.basics.interfaces`
62+
- interface and implementation examples
63+
- `com.example.demo.basics.inheritance`
64+
- inheritance and polymorphism examples
65+
- `com.example.demo.basics.generics`
66+
- generic class example
67+
- `com.example.demo.basics.streams`
68+
- streams and lambda-style collection processing
4669
- `com.example.demo.spring.repository`
4770
- in-memory data storage
4871
- `com.example.demo.spring.service`
@@ -51,6 +74,8 @@ Read these files in order:
5174
- HTTP endpoints and error handling
5275
- `com.example.demo.spring.model`
5376
- request and response models
77+
- `com.example.demo.spring.persistence`
78+
- validation, JPA, H2, and security examples
5479

5580
## Run the app
5681

@@ -72,6 +97,7 @@ Then open:
7297

7398
- `http://localhost:8080/api/students`
7499
- `http://localhost:8080/swagger-ui.html`
100+
- `http://localhost:8080/h2-console`
75101

76102
To stop it:
77103

@@ -110,6 +136,25 @@ curl -X POST http://localhost:8080/api/students \
110136
}'
111137
```
112138

139+
Get secured courses with basic auth:
140+
141+
```bash
142+
curl -u student:password http://localhost:8080/api/courses
143+
```
144+
145+
Create a secured database-backed course:
146+
147+
```bash
148+
curl -u student:password -X POST http://localhost:8080/api/courses \
149+
-H "Content-Type: application/json" \
150+
-d '{
151+
"title": "Spring Data JPA",
152+
"level": "intermediate",
153+
"durationInHours": 7,
154+
"published": true
155+
}'
156+
```
157+
113158
## Swagger and OpenAPI
114159

115160
After starting the app with `./gradlew bootRun`, open:
@@ -144,6 +189,12 @@ Run the tests inside a container:
144189
docker compose run --rm test
145190
```
146191

192+
Different test layers in this repo:
193+
194+
- unit tests: small classes without Spring, such as `StudentTest` and `CourseServiceTest`
195+
- repository tests: JPA + H2 with a Spring Boot integration test, such as `CourseRepositoryTest`
196+
- integration tests: full Spring Boot + MockMvc, such as `StudentControllerTest` and `CourseControllerIntegrationTest`
197+
147198
## GitHub CI
148199

149200
This repo includes a GitHub Actions workflow at `.github/workflows/ci.yml`.
@@ -160,7 +211,8 @@ It runs on every push and pull request, sets up Java 17, and executes:
160211
2. In `Student.java`, add another method such as `averageScore()`.
161212
3. In `StudentService.java`, change how new students are created.
162213
4. In `StudentController.java`, add a new endpoint such as `DELETE /api/students/{id}`.
163-
5. In `StudentControllerTest.java`, add a test before you change the code.
214+
5. In `CourseController.java`, add a new secured endpoint such as `DELETE /api/courses/{id}`.
215+
6. In `CourseControllerIntegrationTest.java`, add a failing test before you change the code.
164216

165217
## Quick concept map
166218

@@ -170,6 +222,13 @@ It runs on every push and pull request, sets up Java 17, and executes:
170222
- `for`: `totalScore`, `subjectSummary`, service mapping methods
171223
- `List`: subjects
172224
- `Map`: scores
225+
- Interfaces: `Notifier`, `EmailNotifier`
226+
- Inheritance: `Person`, `LearningStudent`
227+
- Generics: `Box<T>`
228+
- Streams: `StudentAnalytics`
173229
- Exceptions: `InvalidScoreException`, `StudentNotFoundException`
174-
- Annotations: `@LearningExample`, `@Service`, `@RestController`, `@RestControllerAdvice`
230+
- Annotations: `@LearningExample`, `@Service`, `@RestController`, `@RestControllerAdvice`, `@Entity`, `@Valid`
175231
- Dependency injection: `StudentController` gets `StudentService`, `StudentService` gets `InMemoryStudentRepository`
232+
- Validation: `CreateCourseRequest`
233+
- Persistence: `CourseEntity`, `CourseRepository`, H2
234+
- Security: HTTP basic auth for `/api/courses/**` with user `student` / `password`

docs/README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Learning Docs
2+
3+
This folder explains how to use the repository as a guided Java and Spring Boot course.
4+
5+
## Reading order
6+
7+
1. [Learning Path](./learning-path.md)
8+
2. [Repo Map](./repo-map.md)
9+
3. [Java Basics](./java-basics.md)
10+
4. [Spring Boot](./spring-boot.md)
11+
5. [Testing](./testing.md)
12+
6. [Tooling](./tooling.md)
13+
14+
## Main idea
15+
16+
The repo is intentionally split into two layers:
17+
18+
- `basics`
19+
- small, plain Java examples
20+
- `spring`
21+
- framework examples built on top of the Java basics
22+
23+
Use the code and the tests together. In this repo, tests are part of the documentation.

docs/java-basics.md

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
# Java Basics Guide
2+
3+
This repo covers the most important beginner Java concepts through small, focused classes.
4+
5+
## Classes and objects
6+
7+
Main example:
8+
9+
- `basics/model/Student.java`
10+
11+
What to notice:
12+
13+
- a class defines data and behavior
14+
- `Student student = new Student("Mia", 19);` creates an object
15+
- fields store state like `name`, `age`, `subjects`, and `scores`
16+
17+
## Variables and types
18+
19+
Examples in `Student.java`:
20+
21+
- `long id`
22+
- `String name`
23+
- `int age`
24+
- `boolean active`
25+
- `List<String> subjects`
26+
- `Map<String, Integer> scores`
27+
28+
Learn the difference between:
29+
30+
- primitive types
31+
- `int`, `long`, `boolean`
32+
- object/reference types
33+
- `String`, `List`, `Map`, custom classes
34+
35+
## Constructors
36+
37+
`Student` has overloaded constructors.
38+
39+
Why that matters:
40+
41+
- one constructor gives a simple entry point
42+
- another constructor allows more detailed initialization
43+
44+
This is common in real Java code when you want both convenience and control.
45+
46+
## Methods
47+
48+
Examples:
49+
50+
- `activate()`
51+
- `enroll(String subject)`
52+
- `addScore(String subject, int score)`
53+
- `level()`
54+
- `totalScore()`
55+
56+
Methods:
57+
58+
- receive input through parameters
59+
- use object state
60+
- return values or change state
61+
62+
## `if` and `for`
63+
64+
Examples:
65+
66+
- `if` in `enroll`, `addScore`, and `level`
67+
- `for` in `totalScore` and `subjectSummary`
68+
69+
Key idea:
70+
71+
- `if` chooses behavior
72+
- `for` repeats behavior
73+
74+
## List and Map
75+
76+
`List<String>`:
77+
78+
- keeps ordered values
79+
- used here for subjects
80+
81+
`Map<String, Integer>`:
82+
83+
- stores key/value pairs
84+
- used here for scores
85+
86+
These are core Java collection types you will use constantly.
87+
88+
## Exceptions
89+
90+
Example:
91+
92+
- `InvalidScoreException`
93+
94+
Used in:
95+
96+
- `Student.addScore`
97+
98+
Reason:
99+
100+
- exceptions stop invalid behavior early
101+
- they make failure explicit
102+
103+
## Packages
104+
105+
Packages organize code by topic and responsibility.
106+
107+
Examples:
108+
109+
- `com.example.demo.basics.model`
110+
- `com.example.demo.spring.service`
111+
112+
This is how Java projects stay readable as they grow.
113+
114+
## Annotations
115+
116+
Examples:
117+
118+
- custom annotation: `@LearningExample`
119+
- framework annotations later in Spring: `@Service`, `@RestController`, `@Entity`
120+
121+
Annotations add metadata to classes and methods. In Spring, annotations drive framework behavior.
122+
123+
## Interfaces
124+
125+
Examples:
126+
127+
- `Notifier`
128+
- `EmailNotifier`
129+
130+
Key idea:
131+
132+
- an interface defines a contract
133+
- classes implement that contract
134+
- callers can depend on the interface instead of the concrete class
135+
136+
This becomes very important in framework code and testable design.
137+
138+
## Inheritance and polymorphism
139+
140+
Examples:
141+
142+
- `Person`
143+
- `LearningStudent`
144+
145+
Key idea:
146+
147+
- child classes reuse parent behavior
148+
- child classes can override methods
149+
- polymorphism lets you use the parent type while executing child behavior
150+
151+
## Generics
152+
153+
Example:
154+
155+
- `Box<T>`
156+
157+
Key idea:
158+
159+
- generics let you write reusable classes while keeping type safety
160+
- `Box<String>` and `Box<Integer>` use the same class with different types
161+
162+
## Streams and lambdas
163+
164+
Example:
165+
166+
- `StudentAnalytics`
167+
168+
Key operations:
169+
170+
- `stream()`
171+
- `filter(...)`
172+
- `map(...)`
173+
- `collect(...)`
174+
175+
Use streams when you want to transform or summarize collections in a readable pipeline.
176+
177+
## How to practice
178+
179+
Good small exercises:
180+
181+
1. Add `averageScore()` to `Student`
182+
2. Add a second `Notifier` implementation
183+
3. Add another subclass of `Person`
184+
4. Add a generic method to `Box`
185+
5. Add a new analytics method using streams

0 commit comments

Comments
 (0)