본문 바로가기
Spring

[스프링의 정석] Spring DI 흉내내기

by 리잼 2023. 4. 18.
반응형

Spring DI 흉내내기

1. 변경에 유리한 코드(1) - 다형성, factory method

SportCar car = new SportCar();
		vvv
Truck	 car = new Truck();
		vvv
     	   	vvv
// 다형성을 이용
Car car = new SportCar();
Car car = new Truck();

1. 변경에 유리한 코드(2) - Map과 외부파일

Car car = (Car) getObject("car");
Engine engine = (Engine) getObject("engine");

static Object getObject(String key) throws Exception {
	// config.txt를 읽어서 Properties에 저장
	Properties p = new Properties();
	p.load(new FileReader("config.txt"));
	// 클래스 객체(설계도)를 얻어서
	Class clazz = Class.forName(p.getProperty(key));
	return clazz.newInstance(); // 객체를 생성해서 반환
}

2. 객체 컨테이너 ( ApplicationContext ) 만들기

AppContext ac = new AppContext();
Car car = (Car) ac.getBean("car");
Engine engine = (Engine) ac.getBean("engine");

class AppContext {
	Map map;
	AppContext() {
		map = new HashMap();
		map.put("car", new SportsCar());
		map.put("engine", new Engine());
	}
	Object getBean(String id) { return map.get(id); }
}

3. 자동 객체 등록하기 - Component Scanning

class Car {}				>> @Component class Car {}
class SportsCar extends Car {}		>> @Component class SportsCar extends Car {}
class Truck extends Car {}		>> @Component class Truck extends Car {}
class Engine {}				>> @Component class Engine {}


class AppContext {
	Map map;
	
    AppContext() {
		Properties p = new Properties();
		p.load(new FileReader("config.txt"));
		
        map = new HashMap(p);
		
        for(Object key : map.keySet()) {
		Class clazz = Class.forName((String)map.get(key));
		map.put(key, clazz.newInstance());
        }
	}
}

4. 객체 찾기 - by Name, by Type

AppContext ac = new AppContext();
Car car = (Car) ac.getBean("car"); // 이름(id)으로 찾기
Car car2 = (Car) ac.getBean(Car.class); // 타입으로 찾기

Object getBean(String id) { // 이름으로 찾기
	return map.get(id);
}

Object getBean(Class clazz) { // 타입으로 찾기
	for(Object obj : map.values()) {
		if (clazz.isInstance(obj)) // obj instanceof clazz
			return obj;
	}
	return null;
}

5. 객체를 자동 연결하기(1) - @Autowired

AppContext ac = new AppContext();
Car car = (Car) ac.getBean("car");
Engine engine = (Engine) ac.getBean("engine");
Door door = (Door) ac.getBean("door");

car.engine = engine;
car.door = door;

class Car {
    Engine engine;		>> @Autowired Engine engine;
    Door door;			>> @Autowired Door door;
}

6. 객체를 자동 연결하기(2) - @Resource

AppContext ac = new AppContext();
Car car = (Car) ac.getBean("car");
Engine engine = (Engine) ac.getBean("engine");
Door door = (Door) ac.getBean("door");

car.engine = engine;
car.door = door;

class Car {
    Engine engine;	>> @Resource Engine engine;	>> @Resource(name="engine2") Engine engine;
    Door door;		>> @Resource Door door;		>> @Resource Door door;
}
반응형