Skip to content

Commit 41c4918

Browse files
committed
first commit
0 parents  commit 41c4918

File tree

19 files changed

+545
-0
lines changed

19 files changed

+545
-0
lines changed

.gitignore

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
target/
2+
!.mvn/wrapper/maven-wrapper.jar
3+
!**/src/main/**/target/
4+
!**/src/test/**/target/
5+
6+
### IntelliJ IDEA ###
7+
.idea/modules.xml
8+
.idea/jarRepositories.xml
9+
.idea/compiler.xml
10+
.idea/libraries/
11+
*.iws
12+
*.iml
13+
*.ipr
14+
15+
### Eclipse ###
16+
.apt_generated
17+
.classpath
18+
.factorypath
19+
.project
20+
.settings
21+
.springBeans
22+
.sts4-cache
23+
24+
### NetBeans ###
25+
/nbproject/private/
26+
/nbbuild/
27+
/dist/
28+
/nbdist/
29+
/.nb-gradle/
30+
build/
31+
!**/src/main/**/build/
32+
!**/src/test/**/build/
33+
34+
### VS Code ###
35+
.vscode/
36+
37+
### Mac OS ###
38+
.DS_Store

.idea/.gitignore

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/encodings.xml

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/uiDesigner.xml

Lines changed: 124 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# simple-di

pom.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>dev.hung</groupId>
8+
<artifactId>simple-di</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
11+
<properties>
12+
<maven.compiler.source>17</maven.compiler.source>
13+
<maven.compiler.target>17</maven.compiler.target>
14+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15+
</properties>
16+
17+
</project>
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package dev.hung.inject;
2+
3+
import dev.hung.inject.annotation.Inject;
4+
import dev.hung.inject.annotation.Name;
5+
import dev.hung.inject.annotation.Scope;
6+
7+
import java.lang.reflect.Constructor;
8+
import java.lang.reflect.Field;
9+
import java.util.Arrays;
10+
import java.util.HashMap;
11+
import java.util.Map;
12+
13+
import static dev.hung.inject.annotation.Name.DEFAULT;
14+
import static dev.hung.inject.annotation.Scope.PROTOTYPE;
15+
import static dev.hung.inject.annotation.Scope.SINGLETON;
16+
17+
public class Injector {
18+
private static final Injector instance = new Injector();
19+
20+
private final Map<Key, Value<?>> mapping = new HashMap<>();
21+
22+
private Injector() {}
23+
24+
public static Injector instance() {
25+
return instance;
26+
}
27+
28+
public <K, V extends K> void bind(Class<K> src) {
29+
String scope = getScope(src);
30+
bind(src, DEFAULT, src, scope);
31+
}
32+
33+
public <K, V extends K> void bind(Class<K> src, Class<V> dst) {
34+
String scope = getScope(src);
35+
bind(src, DEFAULT, dst, scope);
36+
}
37+
38+
public <K, V extends K> void bind(Class<K> src, String name, Class<V> dst) {
39+
String scope = getScope(src);
40+
bind(src, name, dst, scope);
41+
}
42+
43+
public <K, V extends K> void bind(Class<K> src, String name, Class<V> dst, String scope) {
44+
Key key = Key.create(src, name);
45+
Value<V> value = new Value<>(dst, scope);
46+
mapping.put(key, value);
47+
}
48+
49+
public void init() {
50+
for (var entry : mapping.entrySet()) {
51+
if (SINGLETON.equals(entry.getValue().getScope())) {
52+
get(entry.getKey());
53+
}
54+
}
55+
}
56+
57+
public void clear() {
58+
mapping.clear();
59+
}
60+
61+
public <T> T get(Key key) {
62+
Value<T> value = (Value<T>) instance.mapping.get(key);
63+
T object;
64+
if (value == null) { // just-in-time injection
65+
object = (T) createObject(key.getClazz());
66+
} else {
67+
if (SINGLETON.equals(value.getScope())) {
68+
if (value.getInstance() == null) {
69+
object = createObject(value.getClazz());
70+
value.setInstance(object);
71+
}
72+
object = value.getInstance();
73+
} else {
74+
object = createObject(value.getClazz());
75+
}
76+
}
77+
return object;
78+
}
79+
80+
private <T> T createObject(Class<T> clazz) {
81+
try {
82+
Constructor<T> constructor = clazz.getConstructor();
83+
T object = constructor.newInstance();
84+
Class<?> current = clazz;
85+
while (current.getSuperclass() != null) {
86+
Field[] fields = current.getDeclaredFields();
87+
for (Field field : fields) {
88+
if (field.isAnnotationPresent(Inject.class)) {
89+
Key key = Key.create(field.getType(), getName(field));
90+
Object fieldValue = get(key);
91+
field.setAccessible(true);
92+
field.set(object, fieldValue);
93+
}
94+
}
95+
current = current.getSuperclass();
96+
}
97+
return object;
98+
} catch (Exception ex) {
99+
System.out.println("Error instantiating " + clazz.getName());
100+
System.out.println(ex.getMessage());
101+
System.out.println(Arrays.toString(ex.getStackTrace()));
102+
return null;
103+
}
104+
}
105+
106+
private String getScope(Class<?> clazz) {
107+
String scope = PROTOTYPE;
108+
if (clazz.isAnnotationPresent(Scope.class)) {
109+
scope = clazz.getAnnotation(Scope.class).value();
110+
}
111+
return scope;
112+
}
113+
114+
private String getName(Field field) {
115+
if (field.isAnnotationPresent(Name.class)) {
116+
return field.getAnnotation(Name.class).value();
117+
}
118+
return "default";
119+
}
120+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package dev.hung.inject;
2+
3+
import java.util.Objects;
4+
5+
import static dev.hung.inject.annotation.Name.DEFAULT;
6+
7+
public class Key {
8+
private final Class<?> clazz;
9+
private final String name;
10+
11+
private Key(Class<?> clazz, String name) {
12+
this.clazz = clazz;
13+
this.name = name;
14+
}
15+
16+
public static Key create(Class<?> clazz, String name) {
17+
return new Key(clazz, name);
18+
}
19+
20+
public static Key create(Class<?> clazz) {
21+
return new Key(clazz, DEFAULT);
22+
}
23+
24+
public Class<?> getClazz() {
25+
return clazz;
26+
}
27+
28+
public String getName() {
29+
return name;
30+
}
31+
32+
@Override
33+
public boolean equals(Object o) {
34+
if (this == o) {
35+
return true;
36+
}
37+
if (o == null || getClass() != o.getClass()) {
38+
return false;
39+
}
40+
Key key = (Key) o;
41+
return Objects.equals(clazz, key.clazz) && Objects.equals(name, key.name);
42+
}
43+
44+
@Override
45+
public int hashCode() {
46+
return Objects.hash(clazz, name);
47+
}
48+
}

0 commit comments

Comments
 (0)