객체 컨테이너(Application context) : 객체 저장소

Map에다 객체 저장소를 만들 것이다.
빨간 코드 부분이 변경되어야 하는 부분이므로,
오른쪽 하얀 코드 상자처럼 바꾸면 코드를 바꿀 부분이 적어진다.
properties는 String,String 으로 저장되고
Map은 String,Object로 저장되기 때문에
이번에는 Map을 사용한다.

<java />
package com.fastcampus.ch3.diCopy2;
import java.io.FileReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
class Car{}
class SportsCar extends Car{}
class Truck extends Car{}
class Engine{}
class AppContext{
Map map; //객체 저장소
AppContext(){
map=new HashMap();
map.put("car",new SportsCar());
map.put("engine",new Engine());
}
Object getBean(String key){
return map.get(key);
}
}
public class Main2 {
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);
}
}
config.txt
<java />car=com.fastcampus.ch3.diCopy2.Truck engine=com.fastcampus.ch3.diCopy2.Engine
실행 결과

위와 같이 하드코딩을 하면 좋지 않기 때문에
코드를 바꿔보자
<java />
package com.fastcampus.ch3.diCopy2;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
class Car{}
class SportsCar extends Car{}
class Truck extends Car{}
class Engine{}
class AppContext{
Map map; //객체 저장소
AppContext() {
try {
Properties p = new Properties();
p.load(new FileReader("config.txt"));
//Propeties에 저장된 내용을 Map에 저장
map=new HashMap(p);
//반복문으로 클래스 이름을 얻어서 객체를 생성해서 다시 map에 저장
//클래스 이름을 이용해서 객체로 바꿔준다
for(Object key: map.keySet()){ //keySet을 돌면서
Class clazz = Class.forName((String)map.get(key)); //클래스 정보를 얻어와서
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();
Car car = (Car) ac.getBean("car");
Engine engine = (Engine) ac.getBean("engine");
System.out.println("car = " + car);
System.out.println("engine = " + engine);
}
}
실행 결과


클래스 앞에다가 @Component를 붙이면,
패키지 안의 클래스들을 검색해서
@Component가 붙은 클래스들을 찾아서
그 클래스의 객체를 생성해서 자동으로 Map에 저장해준다.
config.txt같은 외부 파일을 사용해서 객체를 등록하기도 하지만
클래스 앞의 어노테이션을 붙여서 등록하는 방법도 있다.
guava 사용하기


<java />
package com.fastcampus.ch3.diCopy3;
import com.google.common.reflect.ClassPath;
import org.springframework.util.StringUtils;
import org.springframework.stereotype.Component;
import java.awt.*;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@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 {
//1. 패키지 내의 클래스 목록을 가져온다.
//2. 반복문으로 클래스를 하나씩 읽어와서 @Component가 붙어있는지 확인
//3. @Component가 붙어있으면 객체를 생성해서 map에 저장
ClassLoader classLoader = AppContext.class.getClassLoader();
ClassPath classPath = ClassPath.from(classLoader);
Set<ClassPath.ClassInfo> set = classPath.getTopLevelClasses("com.fastcampus.ch3.diCopy3");
for(ClassPath.ClassInfo classInfo:set){
Class clazz = classInfo.load();
Component component=(Component) clazz.getAnnotation(Component.class);
if(component!=null){
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);
}
}
실행 결과

만약 클래스위에 어노테이션을 주석처리한다면
<java />
//@Component
class Engine{}
Map에 저장되지 않아서
실행결과가 아래와 같이 나온다.

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
패스트캠퍼스 [직장인 실무교육]
프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.
fastcampus.co.kr
'패캠 챌린지' 카테고리의 다른 글
패스트캠퍼스 챌린지 - 30일차 [스프링의 정석:남궁성과 끝까지 간다] (0) | 2023.03.21 |
---|---|
패스트캠퍼스 챌린지 - 29일차 [스프링의 정석:남궁성과 끝까지 간다] (0) | 2023.03.20 |
패스트캠퍼스 챌린지 - 27일차 [스프링의 정석:남궁성과 끝까지 간다] (0) | 2023.03.18 |
패스트캠퍼스 챌린지 - 26일차 : STS3의 프로젝트 import/export (0) | 2023.03.17 |
패스트캠퍼스 챌린지 - 25일차 [스프링의 정석:남궁성과 끝까지 간다] (0) | 2023.03.16 |