3-1 ~ 3-3 Spring DI 흉내내기

서현우·2022년 5월 29일
0

복습

목록 보기
24/34

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

class Car {}
class SportsCar extends Car {}
class Truck extends Car {}

//변경 포인트 2개
SportsCar car = new SportsCar();
Truck car = new Truck();

//다형성
//변경 포인트 1개
Car car = new SportsCar();
Car car = new Truck();

//더 변경 포인트가 적게
//사용하는 코드. 변경 영향 X
Car car = getCar();

//기능 제공. 이것만 변경
static Car getCar() {
	//return new Truck();
	return new SportsCar();
}

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

변경을 더 최소화

//[config.txt]
//car=com.fastcampus.ch3.Truck
car=com.fastcampus.ch3.SportsCar
Car car = getCar();

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

Car뿐만 아니라 다른 것으로도 사용 가능하게

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

static Object getObject(String key) throws Exception {
	Properties p = new Properties();
	p.load(new FileReader("config.txt"));
	
	Class clazz = Class.forName(p.getProperty(key));
	
	return clazz.newInstance();
}

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

AppContext ac = new AppContext();
Car car = (Car)ac.getBean("car");
Engine engin = (Engine)ac.getBean("engine");
class AppContext {
	Map map; //객체 저장소
	
	AppContext() {
		map = new HashMap();
		//변하는 부분. 하드코딩.
		map.put("car", new SpotsCar());
		map.put("engine", new Engine());
	}
	
	Object getBean(String id) {
		return map.get(id);
	}
}
//[config.txt]
car=com.fastcampus.ch3.SportsCar
engine=com.fastcampus.ch3.Engine

//AppContext생성자의 변하는 부분을 외부로 빼냄
//config를 Properties에 저장하고, 다시 Map에 저장
//Properties는 (String,String), Map은(String,Object)이므로 아래처럼 처리
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. 자동으로 객체 등록 하기 - Component Scanning

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

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

AppContext ac = new AppContext();
Car car = (Car)ac.getBean("car"); //이름을 찾기
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.isInstanceof(obj)) //obj instanceof clazz
			return obj;
		}
		return null;
	}
}

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

//수동으로 객체 참조(연결)
AppContext ac = new AppContext();
Car car = (Car)ac.getBean("car");
Engine engine = (Engine)ac.getBean("engine");
Door door = (Door)ac.getBean("door");
//@Autowired붙이면 아래 2줄 필요없음
car.engine = engine;
car.door = door;

class Car {
	Engine engine;
	Door door;
}

//==> 변경
class Car {
	@Autowired Engine engine; //byType
	@Autowired Door door 
}

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

class Car {
	//첫글자 소문자로 바꾼게 name이 됨.
	@Resource Engine engine;
	@Resource Door door;
	//이름 지정도 가능
	@Resource(name="engine2") Engine engine;
}
profile
안녕하세요!!

0개의 댓글