From 68233c45da61c7ae1c5d44c1a7e5fc84ada03e10 Mon Sep 17 00:00:00 2001 From: echo724 Date: Thu, 28 Sep 2023 22:02:18 +0900 Subject: [PATCH] =?UTF-8?q?study:=20DIContainer=20=EB=A6=AC=ED=8E=99?= =?UTF-8?q?=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../di/stage4/annotations/DIContainer.java | 97 +++++++++++-------- 1 file changed, 59 insertions(+), 38 deletions(-) diff --git a/study/src/test/java/di/stage4/annotations/DIContainer.java b/study/src/test/java/di/stage4/annotations/DIContainer.java index 248e359fc7..cd383aa6c2 100644 --- a/study/src/test/java/di/stage4/annotations/DIContainer.java +++ b/study/src/test/java/di/stage4/annotations/DIContainer.java @@ -24,56 +24,77 @@ public DIContainer(final Set> classes) { private Set instantiateBeans(final Set> classes) { final Map, Object> classObjectMap = new HashMap<>(); - final List> sortedClasses = classes.stream() + final List> sortedClasses = sortClassByLessDependnecies(classes); + for (final Class sortedClass : sortedClasses) { + if (sortedClass.getConstructors().length != 0) { + injectConstructorDependency(sortedClass, classObjectMap); + } + injectFieldDependency(sortedClass, classObjectMap); + } + return new HashSet<>(classObjectMap.values()); + } + + private List> sortClassByLessDependnecies(final Set> classes) { + return classes.stream() .sorted(Comparator .comparing(a -> ((Class) a).getDeclaredFields().length) .reversed() ) .collect(Collectors.toList()); - System.out.println("sortedClasses = " + sortedClasses); - for (final Class sortedClass : sortedClasses) { - if (sortedClass.getConstructors().length != 0) { - final Constructor defaultConstructor = sortedClass.getConstructors()[0]; - if (defaultConstructor.getParameterCount() != 0) { - final Class[] parameterTypes = defaultConstructor.getParameterTypes(); - final Object[] parameters = new Object[parameterTypes.length]; - for (int i = 0; i < parameterTypes.length; i++) { - parameters[i] = classObjectMap.get(parameterTypes[i]); - } - try { - putInterfaceOrClass(sortedClass, classObjectMap, defaultConstructor, parameters); - } catch (Exception e) { - throw new RuntimeException(e); - } - } else { - final Constructor constructor = sortedClass.getConstructors()[0]; + } + + private void injectFieldDependency(final Class sortedClass, final Map, Object> classObjectMap) { + Arrays.stream(sortedClass.getDeclaredFields()) + .filter(field -> field.isAnnotationPresent(Inject.class)) + .forEach(field -> { try { - putInterfaceOrClass(sortedClass, classObjectMap, constructor); + field.setAccessible(true); + final Object instance = classObjectMap.getOrDefault(sortedClass, instantiatePrivateConstructor(sortedClass)); + field.set(instance, classObjectMap.get(field.getType())); + classObjectMap.put(sortedClass, instance); } catch (Exception e) { throw new RuntimeException(e); } - } - } else if (sortedClass.getDeclaredFields().length != 0) { - Arrays.stream(sortedClass.getDeclaredFields()) - .filter(field -> field.isAnnotationPresent(Inject.class)) - .forEach(field -> { - try { - field.setAccessible(true); - final Constructor declaredConstructor = sortedClass.getDeclaredConstructors()[0]; - declaredConstructor.setAccessible(true); - final Object instance = declaredConstructor.newInstance(); - field.set(instance, classObjectMap.get(field.getType())); - classObjectMap.put(sortedClass, instance); - } catch (Exception e) { - throw new RuntimeException(e); - } - }); - } + }); + } + + private Object instantiatePrivateConstructor(final Class sortedClass) throws InstantiationException, IllegalAccessException, InvocationTargetException { + final Constructor declaredConstructor = sortedClass.getDeclaredConstructors()[0]; + declaredConstructor.setAccessible(true); + return declaredConstructor.newInstance(); + } + + private void injectConstructorDependency(final Class sortedClass, final Map, Object> classObjectMap) { + final Constructor defaultConstructor = sortedClass.getConstructors()[0]; + if (defaultConstructor.getParameterCount() != 0) { + instantiateBeanWithParameters(sortedClass, classObjectMap, defaultConstructor); + } else { + instantiateBean(sortedClass, classObjectMap, defaultConstructor); + } + } + + private void instantiateBean(final Class sortedClass, final Map, Object> classObjectMap, final Constructor defaultConstructor) { + try { + putInterfaceOrClass(sortedClass, classObjectMap, defaultConstructor); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void instantiateBeanWithParameters(final Class sortedClass, final Map, Object> classObjectMap, final Constructor defaultConstructor) { + final Class[] parameterTypes = defaultConstructor.getParameterTypes(); + final Object[] parameters = new Object[parameterTypes.length]; + for (int i = 0; i < parameterTypes.length; i++) { + parameters[i] = classObjectMap.get(parameterTypes[i]); + } + try { + putInterfaceOrClass(sortedClass, classObjectMap, defaultConstructor, parameters); + } catch (Exception e) { + throw new RuntimeException(e); } - return new HashSet<>(classObjectMap.values()); } - private static void putInterfaceOrClass(final Class sortedClass, final Map, Object> classObjectMap, final Constructor constructor, final Object... parameters) throws InstantiationException, IllegalAccessException, InvocationTargetException { + private void putInterfaceOrClass(final Class sortedClass, final Map, Object> classObjectMap, final Constructor constructor, final Object... parameters) throws InstantiationException, IllegalAccessException, InvocationTargetException { final Class[] interfaces = sortedClass.getInterfaces(); for (final Class anInterface : interfaces) { classObjectMap.put(anInterface, constructor.newInstance(parameters));