<๊ฐ์>
์ ๋ฒ ์๊ฐ์ ์ต์ข ์ ์ผ๋ก ํ ๊ฒ์ DI๋ฅผ ํ๋ด๋ด์ด ๋ณ๊ฒฝ์ ์ ๋ฆฌํ ์ฝ๋๋ฅผ ๋ง๋๋ ๊ฒ์ด์๋ค.
DI๋ ์์กด์ฑ ์ฃผ์ ์ผ๋ก, ์ด๋ค ๊ฐ์ฒด๋ฅผ ์์ค์ฝ๋ ๋ด๋ถ์์ ์ ์ธํ๋ ๊ฒ์ด ์๋๋ผ, ์ธ๋ถ์์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ํ ์์ค์ฝ๋ ๋ด๋ถ๋ก ์ฃผ์ ํ๋ ๊ฒ์ ์๋ฏธํ๋ค.
์ ๋ฒ ํฌ์คํ ์์๋ DI๋ฅผ ํ๋ด๋ด๊ธฐ ์ํ์ฌ ๊ฐ์ฒด ์์ฑ ๊ธฐ๋ฅ์ ํ๋ ๋งค์๋๋ฅผ ์ด์ฉํ๋ค. ํด๋น ๋งค์๋์ ์ธ์๋ก ๋ณด๋ธ ๊ฐ์ด properties์ Key ๊ฐ์ผ๋ก ์๋ค๋ฉด, ๋งค์๋๋ ํด๋น Key์ ๋์๋๋ Value (์ ์ฒด์ด๋ฆ = ๊ฒฝ๋ก์ฃผ์.ํด๋์ค์ด๋ฆ)๋ฅผ ์ด์ฉํ์ฌ Class class ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ณ , ๊ทธ Class class ๊ฐ์ฒด๋ฅผ ์ด์ฉํ์ฌ ์ค์ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ๋ฐํ ํ๋ค.
Properties๋ map์ฒ๋ผ <K,V>ํ์์ ๋๊ณ ์์ผ๋, K,V์ ์ค์ง String ๊ฐ๋ง ๊ฐ๋ฅํ๋ค.
์ด๋ฒ์๋ ๊ฐ์ฒด ์ปจํ ์ด๋๋ผ๋ ๊ฐ์ฒด ์ ์ฅ์๋ฅผ ๋ฐ๋ก ๋ง๋ค๊ณ , ๊ทธ ์์ ๊ฐ์ฒด๋ฅผ ์ง์ด๋ฃ์ด ํ์ํ ๋ ๊บผ๋ด์ฐ๋ ๋ฐฉ์์ผ๋ก DI๋ฅผ ๊ตฌํํด๋ณด๊ฒ ๋ค. ์ด ๋ํ ๊ฐ์ฒด ์ปจํ ์ด๋์ ๋ฏธ๋ฆฌ ๋ง๋ค์ด๋์ ๊ฐ์ฒด๋ฅผ ๋นผ์ ์ฐ๋ ๊ฑฐ๋ผ, ์์ค์ฝ๋ ๋ด๋ถ์์ ๊ฐ์ฒด๋ฅผ ์์ฑํ์ง ์๋๋ค.
๊ทธ๋์ DI๋ผ๊ณ ๋ณผ ์ ์๋ค.
** ๊ฐ์ฒด ์ปจํ ์ด๋ ์ฌ์ฉ๊ณผ ์ธ๋ถ ํ์ผ ํ์ฉ์ ์ฐจ์ด์ **
์ธ๋ถ ํ์ผ ์ด์ฉํ๋ ๋ก์ง์ ์ธ๋ถ ํ์ผ ์์ <๊ฐ์ฒด ์ด๋ฆ, ๊ฐ์ฒด์ ๊ฒฝ๋ก์ฃผ์.ํด๋์ค์ด๋ฆ>์ K V ํ์์ map์ด ์์๋ค.
์ฌ๊ธฐ์ ๊ฒฝ๋ก์ฃผ์๋ฅผ ์ด์ฉํ์ฌ, ํด๋น ํด๋์ค์ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๋ฝ๊ณ , ๊ทธ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํด ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ๋ฐํํ๋ค.
๊ฐ์ฒด ์ปจํ ์ด๋๋ ์ปจํ ์ด๋ ์์ Map ํ์์ผ๋ก <๊ฐ์ฒด ์ด๋ฆ, ๊ฐ์ฒด>๊ฐ ์กด์ฌํ๋ค.
๊ฐ์ฒด๋ฅผ Reflection API ์ฌ์ฉํ์ฌ ๋ง๋ค ํ์ ์์ด ๋ฐ๋ก ๊บผ๋ด๋ค๊ฐ ์ฐ๋ฉด ๋๋ค.
**์ฐธ๊ณ **
Reflection Api ๋
ํด๋์ค์ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์ด์ฉํ์ฌ ์ค์ ํด๋น ํด๋์ค์
๋ณ์๋ ๋งค์๋๋ฅผ ๊ตฌํํ์ฌ ์ฌ์ฉํ ์ ์๊ฒ ํด์ฃผ๋ ๊ธฐ๋ฅ
์ผ์ ์ํ ์๋ฅผ ๋ค๋ฉด, ์ธ๋ถ ํ์ผ ์ด์ฉ์ ๋์ฅ๊ณ ์์ ์ฌ๋ฃ๋ฅผ ๊บผ๋ด์ ๋ด๊ฐ ์ง์ ์๋ฆฌ ํด์ ๋จน๋ ๊ฒ์ด๊ณ , ๊ฐ์ฒด ์ปจํ ์ด๋๋ ๋์ฅ๊ณ ์ ์๋ง๊ฐ ํด๋๊ณ ๊ฐ ์๋ฆฌ๋ฅผ ๋ฐ๋ก ๊บผ๋ด ๋จน๋ ๊ฒ์ด๋ค.
1. Map ์ด์ฉํ์ฌ ๊ฐ์ฒด ์ปจํ ์ด๋ ๊ตฌํ
class Car {}
class SportsCar extends Car {}
class Truck extends Car{}
class Engine {}
class AppContext {
//๊ฐ์ฒด ์ ์ฅ์
Map map ;
// ์์ฑ์ -> ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ฉด ํ ํ๋๋ค์ ์์ ์ ์
AppContext(){
map = new HashMap<>();
try {
// properties์ config์ <K,V> ๋ด์ฉ ๋ฐ์์ค๊ธฐ
Properties p = new Properties();
p.load(new FileReader("config.txt"));
//proporties์ ์๋ ๋ด์ฉ์ map์ ์ ์ฅ ์์ง map ์์๋ <๊ฐ์ฒด์ด๋ฆ, ๊ฒฝ๋ก์ฃผ์>
map = new HashMap<>(p);
// ๋ฐ๋ณต๋ฌธ์ผ๋ก <K,V>๋ฅผ <๊ฐ์ฒด์ด๋ฆ, ๊ฐ์ฒด>๋ก ๊ฐฑ์
// Map์ Key๊ฐ์ด ์ค๋ณต ์ ์ฅ ์๋จ์ ์ด์ฉ. ์ ค ์ต๊ทผ ๋ด์ฉ์ผ๋ก ๊ฐฑ์ ๋จ.
for (Object key :
map.keySet()) {
// map์ Value ์ด์ฉ, Map์ <String, Object>์ด๊ธฐ ๋๋ฌธ์ ๋ค์ Value๋ฅผ String์ผ๋ก ํ ๋ณํ ํด์ค์ผํจ.
// ๊ฒฝ๋ก์ฃผ์์ ํด๋นํ๋ ํด๋์ค์ ๋ฉํ๋ฐ์ดํฐ๋ฅผ clazz์ ์ ์ฅ
Class clazz = Class.forName((String) map.get(key));
// map ๊ฐฑ์ , ๊ฒฝ๋ก ์ฃผ์ ์ด์ฉํด ๋ง๋ ์ง์ง ๊ฐ์ฒด๋ก
map.put(key, clazz.newInstance());
}
} catch (Exception e) {
e.printStackTrace();
}
}
//๊ฐ์ฒด ์ด๋ฆ์ ์ธ์๋ก ๋ฃ์ผ๋ฉด ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ๋งค์๋
Object getBean(String key) {
return map.get(key);
}
}
public class main2 {
public static void main(String[] args) throws Exception {
// ์ ์ฅ์ ์์ฑ
AppContext ac = new AppContext();
// ๋งค์๋์ ๋ฐํํ์
์ด Object ์ด๋ฏ๋ก, ๋ฐ์ ๋ ํ๋ณํ ํ์
Car car = (Car)ac.getBean("car");
Engine engine = (Engine)ac.getBean("engine");
System.out.println("car = " + car);
System.out.println("engine = " + engine);
}
}
2. ์ธ๋ถ ํ์ผ ์์ด ์๋์ผ๋ก Map์ <๊ฐ์ฒด ์ด๋ฆ, ๊ฐ์ฒด>๋ก ์ฑ์ฐ๊ณ ์ฐ๋ ๋ฒ
// ์ด๋
ธํ
์ด์
๋ฌ๋ ค์๋ ๊ฒ๋ง ์ฐพ์์ ๊ฐ์ฒด ์ปจํ
์ด๋(map)์์ ๋ฃ์ด์ค๋ค.
// map์์ ์์ผ๋ฉด getBeans ํจ์๊ฐ ์ฐพ์ ์ ์๊ธฐ์ ๊ฐ์ฒด๊ฐ null๋ก ๋ฌ๋ค.
@Component class Car {}
@Component class SportsCar extends Car {}
@Component class Truck extends Car{}
@Component class Engine {}
class AppContext {
Map map ; //๊ฐ์ฒด ์ ์ฅ์
AppContext(){
map = new HashMap();
doComponentScan();
}
private void doComponentScan() {
try {
ClassLoader classLoader = AppContext.class.getClassLoader();
ClassPath classPath = ClassPath.from(classLoader);
// 1. ํจํค์ง ๋ด์ ๋ชจ๋ ํด๋์ค๋ฅผ ์ฝ์ด์ Set์ ์ ์ฅ
Set<ClassPath.ClassInfo> set = classPath.getTopLevelClasses("com.fastcampus.ch3.diCopy3");
// 2. ๋ฐ๋ณต๋ฌธ์ผ๋ก ํด๋์ค๋ฅผ ํ๋์ฉ ์ฝ์ด์์ @Component ๋ถ์ด ์๋์ง ํ์ธ
for (ClassPath.ClassInfo classInfo :
set) {
Class clazz = classInfo.load();
Component component = (Component) clazz.getAnnotation(Component.class);
// 3. @Component๊ฐ ๋ถ์ด ์์ผ๋ฉด, ๊ฐ์ฒด๋ฅผ ์์ฑํด์ map์ ์ ์ฅ
if(component != null ){
// id(๊ฐ์ฒด ์ด๋ฆ)์ ํด๋์ค์ ์ฒซ ๋๋ฌธ์๋ฅผ ์๋ฌธ์๋ก ๋ง๋ค์ด ์ ์ฅ Car -> car
String id = StringUtils.uncapitalize(classInfo.getSimpleName());
map.put(id,clazz.newInstance());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Object getBean(String key) {return map.get(key);}
}
public class main3 {
public static void main(String[] args) throws Exception {
AppContext ac = new AppContext();
Car car = (Car)ac.getBean("car");
Engine engine = (Engine)ac.getBean("engine");
System.out.println("car = " + car);
System.out.println("engine = " + engine);
}
}
3. ์ค์ค๋ก ํด๋ณด๊ธฐ
class Car {}
class SportsCar extends Car {}
class Truck extends Car{}
class Engine {}
class AppContext {
//๊ฐ์ฒด ์ ์ฅ์
Map map ;
// ์์ฑ์ -> ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ฉด ํ ํ๋๋ค์ ์์ ์ ์
AppContext(){
map = new HashMap();
try {
// properties์ config์ <K,V> ๋ด์ฉ ๋ฐ์์ค๊ธฐ
Properties p = new Properties();
p.load(new FileReader("config.txt"));
//proporties์ ์๋ ๋ด์ฉ์ map์ ์ ์ฅ(์๋ก ์ด๊ธฐํ) ์์ง map ์์๋ <๊ฐ์ฒด์ด๋ฆ, ๊ฒฝ๋ก์ฃผ์>
map = new HashMap<>(p);
// ๋ฐ๋ณต๋ฌธ์ผ๋ก <K,V>๋ฅผ <๊ฐ์ฒด์ด๋ฆ, ๊ฐ์ฒด>๋ก ๊ฐฑ์
for (Object obj :
map.keySet()) {
Class clazz = Class.forName((String)map.get(obj));
map.put(obj, clazz.newInstance());
}
// Map์ Key๊ฐ์ด ์ค๋ณต ์ ์ฅ ์๋จ์ ์ด์ฉ. ์ ค ์ต๊ทผ ๋ด์ฉ์ผ๋ก ๊ฐฑ์ ๋จ.
// map์ Value ์ด์ฉ, Map์ <String, Object>์ด๊ธฐ ๋๋ฌธ์ ๋ค์ Value๋ฅผ String์ผ๋ก ํ ๋ณํ ํด์ค์ผํจ.
// ๊ฒฝ๋ก์ฃผ์์ ํด๋นํ๋ ํด๋์ค์ ๋ฉํ๋ฐ์ดํฐ๋ฅผ clazz์ ์ ์ฅ
// map ๊ฐฑ์ , ๊ฒฝ๋ก ์ฃผ์ ์ด์ฉํด ๋ง๋ ์ง์ง ๊ฐ์ฒด๋ก
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
//๊ฐ์ฒด ์ด๋ฆ์ ์ธ์๋ก ๋ฃ์ผ๋ฉด ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ ๋งค์๋
Object getBean(String key){return map.get(key);}
}
public class main2Work {
public static void main(String[] args) throws Exception {
// ์ ์ฅ์ ์์ฑ
AppContext ac = new AppContext();
// ๋งค์๋์ ๋ฐํํ์
์ด Object ์ด๋ฏ๋ก, ๋ฐ์ ๋ ํ๋ณํ ํ์
Car car = (Car)ac.getBean("car");
Engine engine = (Engine)ac.getBean("engine");
System.out.println("car = " + car);
System.out.println("engine = " + engine);
}
}
car = com.fastcampus.ch3.diCopy2.Truck
engine = com.fastcampus.ch3.diCopy2.Engine
๋๋ฒ ์งธ ๋ฐฉ๋ฒ์ผ๋ก Map์ ์๋ ๋ฑ๋กํ๋ ๊ฒฝ์ฐ,
ํจํค์ง ์ธ๋ถ์ ํด๋์ค๋ค์ ๊ฒฝ๋ก๋ฅผ ์ธ๋ถ๋ก ์ค์ ํด๋ ๋ชป ๊ฐ์ ธ์จ๋ค.
์ด๋ค ํจ์์ ๋ถ์ด ์๋ ์ด๋ ธํ ์ด์ ์ ์ญ์ ํ๋ฉด doComponentScan ๋งค์๋๊ฐ ํด๋น ์ด๋ ธํ ์ด์ ์ด ์ญ์ ๋ ํด๋์ค๋ฅผ Map์ ์ ์ฅํ์ง ์๋๋ค.