This repository is a beginner-friendly sample that implements a minimal dependency-injection (DI)
container using jakarta.inject annotations (@Named / @Inject).
It is designed so you can follow where objects are created and how dependencies are injected.
- Automatically scanning classes annotated with
@Named - Creating instances with a no-arg constructor
- Injecting dependencies into fields annotated with
@Inject - A simple Controller → Service → Repository flow
- Java 25 (aligned with
pom.xml) - Maven
Check your Java version:
java -versionCheck your Maven version:
mvn -version- Resolve dependencies and build
mvn -DskipTests package- Run the field-injection sample
mvn -q -DskipTests exec:java -Dexec.mainClass=dev.sobue.sample.di.field.FieldInjectionApplicationIf you see logs starting with start app and a result = ... line, the run succeeded.
- Run the constructor-injection sample
mvn -q -DskipTests exec:java -Dexec.mainClass=dev.sobue.sample.di.constructor.ConstructorInjectionApplicationmvn testsrc/main/java/dev/sobue/sample/di/field/FieldInjectionApplication.java
Entry point. Initializes the DI container and invokes the controller.src/main/java/dev/sobue/sample/di/field/container/Context.java
The DI container implementation: scanning, instantiation, and injection.src/main/java/dev/sobue/sample/di/field/controller/service/repository
Sample layer implementations.src/main/java/dev/sobue/sample/di/constructor/ConstructorInjectionApplication.java
Entry point for constructor injection.src/main/java/dev/sobue/sample/di/constructor/container/Context.java
Constructor-injection container implementation.src/main/java/dev/sobue/sample/di/constructor/controller/service/repository
Constructor-injection sample layers.src/test/java/dev/sobue/sample/di/field
Unit tests.
Context.initialize(...)scans the target package for@Namedclasses and registers instances.- It then injects dependencies into fields annotated with
@Inject, resolved by type. - If multiple candidates match the same type, an exception is thrown (this is a simple container).
no default constructor
The@Namedclass must have a no-arg constructor.not single object
Multiple implementations for the same type were registered. Adjust the resolution logic inContext.getBean(...).
- JDK 25 Documentation: https://docs.oracle.com/en/java/javase/25/
- Jakarta Dependency Injection: https://jakarta.ee/specifications/dependency-injection/
- Jakarta EE Specifications: https://jakarta.ee/specifications/
- SonarCloud
- GitHub Actions verifies Maven on JDK 25 and JDK 26.
- SonarCloud analysis runs on JDK 25 when the
SONAR_TOKENsecret is configured.
mvn versions:update-properties -DgenerateBackupPoms=false -Dproperties=jakarta.inject-api.version,commons-codec.version,logback.version,lombok.version,junit.version,mockito.version,maven-clean-plugin.version,maven-enforcer-plugin.version,maven-checkstyle-plugin.version,maven-resources-plugin.version,maven-compiler-plugin.version,maven-surefire-plugin.version,maven-source-plugin.version,maven-site-plugin.version,maven-jxr-plugin.version,maven-project-info-reports-plugin.version,maven-pmd-plugin.version,maven-javadoc-plugin.version,jacoco-maven-plugin.version,clover-maven-plugin.version,spotbugs-maven-plugin.version,sonar-maven-plugin.version,checkstyle.version,pmd.version