{"id":24672427,"url":"https://github.com/parsashhub/javadependencyinjectionfromscratch","last_synced_at":"2025-03-21T14:44:26.644Z","repository":{"id":253501723,"uuid":"841861577","full_name":"parsashhub/JavaDependencyInjectionFromScratch","owner":"parsashhub","description":"Simple Dependency Injection for Java","archived":false,"fork":false,"pushed_at":"2024-08-26T09:25:45.000Z","size":50,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-26T10:13:36.321Z","etag":null,"topics":["dependency-injection","di-framework","java"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/parsashhub.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-13T07:33:24.000Z","updated_at":"2024-08-26T09:25:49.000Z","dependencies_parsed_at":"2024-08-26T09:38:12.603Z","dependency_job_id":"610eedf1-c628-4b0e-bb56-f11845298f8f","html_url":"https://github.com/parsashhub/JavaDependencyInjectionFromScratch","commit_stats":null,"previous_names":["parsashhub/javadependencyinjectionfromscratch"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parsashhub%2FJavaDependencyInjectionFromScratch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parsashhub%2FJavaDependencyInjectionFromScratch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parsashhub%2FJavaDependencyInjectionFromScratch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/parsashhub%2FJavaDependencyInjectionFromScratch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/parsashhub","download_url":"https://codeload.github.com/parsashhub/JavaDependencyInjectionFromScratch/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244815972,"owners_count":20515023,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dependency-injection","di-framework","java"],"created_at":"2025-01-26T10:13:42.327Z","updated_at":"2025-03-21T14:44:26.623Z","avatar_url":"https://github.com/parsashhub.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n---\n\n# Custom Dependency Injection Framework in Java\n\nThis repository contains a custom implementation of a Dependency Injection (DI) framework in Java, inspired by the\nconcepts used in popular frameworks like Spring. The project demonstrates how DI works and includes examples of\nboth `singleton` and `prototype` scopes.\n\n## Overview\n\nThis project implements a custom Dependency Injection (DI) framework in Java, similar to Spring. It provides annotations\nfor managing dependencies and allows components to be injected into other components automatically.\n\n## Table of Contents\n\n- [Introduction](#Introduction)\n- [Prerequisites](#Prerequisites)\n- [Installation](#installation)\n- [Project Structure](#project-structure)\n- [Annotations](#annotations)\n    - [@Component](#component)\n    - [@Inject](#inject)\n    - [@Autowired](#autowired)\n    - [@Qualifier](#qualifier)\n    - [@PostConstruct](#postConstruct)\n    - [@Value](#value)\n- [Usage](#usage)\n    - [Component Registration](#component-registration)\n    - [Dependency Injection](#dependency-injection)\n    - [Qualifier Usage](#qualifier-usage)\n- [Example](#example)\n- [License](#license)\n\n## Introduction\n\nDependency Injection is a design pattern used to implement IoC (Inversion of Control), allowing the creation of\ndependent objects outside of a class and providing those objects to the class. This project is a simplified version of a\nDI container that can scan packages, resolve dependencies, and manage the lifecycle of components.\n\n### Dependency Injection (DI)\n\nDI is a design pattern that allows an object to receive its dependencies from an external source rather than creating\nthem itself. This makes code more modular, testable, and maintainable.\n\n### Inversion of Control (IoC)\n\nIn short, \"Don't call us, we'll call you.\"\n\n- Inversion of Control (IoC) is a design principle. It is used to invert different kinds of controls (ie. object\n  creation or dependent object creation and binding ) in object-oriented design to achieve loose coupling.\n- Dependency injection one of the approach to implement the IoC.\n- IoC helps to decouple the execution of a task from implementation.\n- IoC helps it focus a module on the task it is designed for.\n- IoC prevents side effects when replacing a module.\n\n### Annotations\n\nAnnotations in Java provide metadata for the code and can be used to mark classes, fields, methods, etc., for special\nprocessing. In our DI framework, annotations like @Component, @Inject, @Scope, and @PostConstruct help manage the\ncomponents and their dependencies.\n\n### Scopes\n\nScopes define the lifecycle of an object. The two common scopes are:\n\n- Singleton: A single instance is created and shared throughout the application.\n- Prototype: A new instance is created every time it's requested.\n\n### Features\n\n- **Custom DI Container**: Manages the creation and injection of dependencies.\n- **Singleton Scope**: Components are created once and shared across the application.\n- **Prototype Scope**: A new instance of a component is created every time it is requested.\n- **Annotation-Based Configuration**: Components are identified and managed using annotations like `@Component`\n  and `@Scope`.\n- **Package Scanning**: Automatically detects and registers components from a specified package.\n\n\n## Prerequisites\n\n- Java Development Kit (JDK) 8 or higher\n- An IDE or text editor to view and edit the code\n\n## Installation\n\n1. **Clone the repository**:\n\n   ```bash\n   git clone https://github.com/parsashhub/JavaDependencyInjectionFromScratch.git\n   ```\n\n2. **Navigate to the project directory**:\n\n   ```bash\n   cd JavaDependencyInjectionFromScratch\n   ```\n\n3. **Compile the project**:\n\n   Use a Java IDE (e.g., IntelliJ IDEA, Eclipse) or the command line:\n\n   ```bash\n   javac -d bin src/com/example/*.java\n   ```\n\n4. **Run the project**:\n\n   ```bash\n   java -cp bin com.example.Main\n   ```\n\n## Project Structure\n\n```\n/src\n│\n├── /com/example\n│   ├── /DI \n│   │    ├── ApplicationContext.java           // Main dependency injection context\n│   │    ├── BeanDefinition.java             \n│   │    └── BeanFactory.java            \n│   ├── /Enums               // Enum for bean scopes (SINGLETON, PROTOTYPE)\n│   │    └── Scope.java\n│   ├── /annotations\n│   │    ├── Component.java            \n│   │    ├── Autowired.java            \n│   │    ├── Inject.java               \n│   │    ├── PostConstruct.java               \n│   │    ├── Value.java               \n│   │    └── Qualifier.java            \n│   ├── /interfaces\n│   │    └── IGreetingService.java            \n│   ├── A.java        \n│   ├── B.java        \n│   ├── C.java                      // A, B, C classes create a circular dependency exception\n│   ├── AppConfig.java              // example of @Value usage\n│   ├── EnglishGreetingService.java // Singleton component with qualifier\n│   ├── SpanishGreetingService.java // Prototype component with qualifier\n│   ├── GreetingClient.java         // Client class using injected services\n│   ├── MyClient.java         \n│   ├── MyService.java         \n│   └── Main.java                   // Main class to run the example\n```\n\n## Annotations\n\n### `@Component`\n\nMarks a class as a component, making it eligible for DI. Components can have different scopes.\n\n- **Usage**: Place this annotation on classes you want to manage as beans.\n- **Scope Options**:\n    - `Scope.SINGLETON` (default): A single instance is shared.\n    - `Scope.PROTOTYPE`: A new instance is created each time it is injected.\n\n### `@Inject`\n\nIndicates that a dependency should be injected. Works on fields, constructors, or methods.\n\n- **Usage**: Place this annotation on fields or constructors to indicate where dependencies should be injected.\n\n### `@Autowired`\n\nSimilar to `@Inject`, it marks a dependency for injection. Commonly used in Spring-based projects.\n\n- **Usage**: Can be used interchangeably with `@Inject` on fields, constructors, or methods.\n\n### `@Qualifier`\n\nUsed to resolve ambiguity when multiple implementations of an interface are available.\n\n- **Usage**: Place this annotation on a field, constructor, or method along with `@Inject` or `@Autowired` to specify\n  the desired implementation.\n\n### `@PostConstruct`\nUsed to invoke a method after the construction is done.\n\n- **Usage**: Place this annotation on a method along with `@PostConstruct` to specify\n  the desired implementation.\n\n### `@Value`\nUsed to inject a field from application.properties file.\n\n- **Usage**: Place this annotation on a filed along with `@Value(\"${app.name}\")` to specify\n  the desired implementation.\n\n## Usage\n\n### Component Registration\n\nTo register a class as a component:\n\n```java\n\n@Component(scope = Scope.SINGLETON)\npublic class MyService {\n    // Class content\n}\n```\n\n### Dependency Injection\n\nInject dependencies into another class:\n\n```java\n\n@Component\npublic class MyClient {\n\n    @Inject // or @Autowired\n    private MyService myService;\n\n    public void performAction() {\n        myService.doSomething();\n    }\n}\n```\n\n### Qualifier Usage\n\nWhen multiple implementations of an interface exist:\n\n```java\n\n@Component(scope = Scope.SINGLETON)\n@Qualifier(\"englishGreeting\")\npublic class EnglishGreetingService implements GreetingService {\n    // Implementation\n}\n\n@Component(scope = Scope.PROTOTYPE)\n@Qualifier(\"spanishGreeting\")\npublic class SpanishGreetingService implements GreetingService {\n    // Implementation\n}\n\n@Component\npublic class GreetingClient {\n\n    @Autowired\n    @Qualifier(\"englishGreeting\")\n    private GreetingService greetingService;\n\n    public void greet(String name) {\n        greetingService.greet(name);\n    }\n}\n```\n\n## Example\n\n### Main Class\n\nThe `Main.java` file initializes the DI container and retrieves the components:\n\n```java\npublic class Main {\n    public static void main(String[] args) {\n        DIContainer container = new DIContainer(\"com.example\");\n\n        GreetingClient client = container.getComponent(GreetingClient.class);\n        client.greet(\"John\");\n\n        GreetingService spanishService = container.getComponent(SpanishGreetingService.class);\n        spanishService.greet(\"Juan\");\n    }\n}\n```\n\n### Expected Output\n\nWhen you run the `Main` class, you should see:\n\n```\nHello, John!\n¡Hola, Juan!\n```\n\n## License\n\nThis project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparsashhub%2Fjavadependencyinjectionfromscratch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fparsashhub%2Fjavadependencyinjectionfromscratch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fparsashhub%2Fjavadependencyinjectionfromscratch/lists"}