Skip to content

Commit 0b8a4d3

Browse files
committed
improve code comments
1 parent fd1bd2a commit 0b8a4d3

File tree

3 files changed

+73
-31
lines changed

3 files changed

+73
-31
lines changed

Diff for: src/main/java/dev/keva/ioc/KevaIoC.java

+53-12
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import dev.keva.ioc.annotation.*;
44
import dev.keva.ioc.core.BeanContainer;
5-
import dev.keva.ioc.core.CircularDetector;
5+
import dev.keva.ioc.core.CircularDependencyDetector;
66
import dev.keva.ioc.core.ImplementationContainer;
77
import dev.keva.ioc.exception.IoCBeanNotFound;
88
import dev.keva.ioc.exception.IoCCircularDepException;
@@ -19,10 +19,48 @@
1919
import java.net.URISyntaxException;
2020
import java.util.*;
2121

22+
/**
23+
* KevaIoC - A lightweight dependency injection and inversion of control container.
24+
* The class provides mechanisms for scanning, registering, and resolving dependencies among components
25+
* marked with specific annotations within a Java application. It supports component lifecycle management
26+
* through dependency injection patterns such as constructor injection, setter injection, and field injection.
27+
*
28+
* Key Features:
29+
* - Component scanning based on package names and annotations.
30+
* - Registration of components, either predefined or discovered via component scanning.
31+
* - Resolution of components ensuring dependencies are satisfied and handling lifecycle appropriately.
32+
* - Detection and handling of circular dependencies among components.
33+
* - Exception handling to manage errors related to bean instantiation, circular dependencies, and missing beans.
34+
*
35+
* Usage:
36+
* - To use this container, the user must call the static method `initBeans` with the main class and any predefined beans.
37+
* - Beans can be fetched using the `getBean` method by providing the class type.
38+
*
39+
* Method Execution Flow:
40+
* 1. `initBeans`: Initializes the IoC container with an optional list of predefined beans. This method handles all
41+
* initial setup including scanning components, registering beans, and handling any exceptions that occur during initialization.
42+
* 2. `initWrapper`: Called by `initBeans`, this method performs the detailed initialization sequence including:
43+
* a. Registering predefined beans if provided.
44+
* b. Component scanning using annotations to discover and register additional beans.
45+
* 3. `init`: Helper method called by `initWrapper` to perform scanning within a specific package, it handles:
46+
* a. Registering the container itself as a bean.
47+
* b. Scanning for implementations, configurations, and components within the package.
48+
* 4. `scanImplementations`, `scanConfigurationClass`, `scanComponentClasses`: These methods are used to find and register beans based on different criteria like annotated classes or methods within classes.
49+
* 5. `newInstanceWrapper`: Handles instantiation of a class, managing circular dependencies and injecting necessary dependencies.
50+
* 6. `_getBean`: Overloaded methods that resolve and return beans by type, handling instantiation if not already present in the container.
51+
* 7. `fieldInject`, `setterInject`: Methods for performing dependency injection into annotated fields and setter methods respectively.
52+
*
53+
* Exceptions:
54+
* - The class handles various exceptions that may arise during the operation of the IoC container such as `IoCException`,
55+
* `IoCBeanNotFound`, and `IoCCircularDepException`. These are typically re-thrown as `IoCException` with appropriate error messages.
56+
*
57+
* This class is part of the `dev.keva.ioc` package and depends on various other classes within the same package and third-party
58+
* libraries such as `org.reflections.Reflections` for component scanning based on annotations.
59+
*/
2260
public class KevaIoC {
2361
private final BeanContainer beanContainer = new BeanContainer();
2462
private final ImplementationContainer implementationContainer = new ImplementationContainer();
25-
private final CircularDetector circularDetector = new CircularDetector();
63+
private final CircularDependencyDetector circularDependencyDetector = new CircularDependencyDetector();
2664

2765
private KevaIoC() {
2866
}
@@ -121,7 +159,6 @@ private void scanConfigurationClass(List<Class<?>> classes) throws IoCCircularDe
121159
Class<?> configurationClass = configurationClassesQ.removeFirst();
122160
try {
123161
Object instance = configurationClass.getConstructor().newInstance();
124-
circularDetector.detect(configurationClass);
125162
scanConfigurationBeans(configurationClass, instance);
126163
} catch (IoCBeanNotFound e) {
127164
configurationClassesQ.addLast(configurationClass);
@@ -160,17 +197,21 @@ private void scanConfigurationBeans(Class<?> clazz, Object classInstance) throws
160197

161198
private Object newInstanceWrapper(Class<?> clazz) throws InvocationTargetException,
162199
IllegalAccessException, InstantiationException, NoSuchMethodException, IoCBeanNotFound, IoCCircularDepException {
163-
if (beanContainer.containsBean(clazz)) {
164-
return beanContainer.getBean(clazz);
165-
}
200+
circularDependencyDetector.startInstantiation(clazz);
166201

167-
circularDetector.detect(clazz);
202+
try {
203+
if (beanContainer.containsBean(clazz)) {
204+
return beanContainer.getBean(clazz);
205+
}
168206

169-
Object instance = newInstance(clazz);
170-
beanContainer.putBean(clazz, instance);
171-
fieldInject(clazz, instance);
172-
setterInject(clazz, instance);
173-
return instance;
207+
Object instance = newInstance(clazz);
208+
beanContainer.putBean(clazz, instance);
209+
fieldInject(clazz, instance);
210+
setterInject(clazz, instance);
211+
return instance;
212+
} finally {
213+
circularDependencyDetector.finishInstantiation(clazz);
214+
}
174215
}
175216

176217
private Object newInstance(Class<?> clazz) throws IllegalAccessException,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package dev.keva.ioc.core;
2+
3+
import dev.keva.ioc.exception.IoCCircularDepException;
4+
5+
import java.util.*;
6+
7+
public class CircularDependencyDetector {
8+
private final Set<Class<?>> instantiationInProgress = new HashSet<>();
9+
10+
public void startInstantiation(Class<?> clazz) throws IoCCircularDepException {
11+
if (instantiationInProgress.contains(clazz)) {
12+
throw new IoCCircularDepException("Circular dependency detected while instantiating " + clazz.getName());
13+
}
14+
instantiationInProgress.add(clazz);
15+
}
16+
17+
public void finishInstantiation(Class<?> clazz) {
18+
instantiationInProgress.remove(clazz);
19+
}
20+
}

Diff for: src/main/java/dev/keva/ioc/core/CircularDetector.java

-19
This file was deleted.

0 commit comments

Comments
 (0)