Burninghering's Blog
article thumbnail

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

 

 Map에다 객체 저장소를 만들 것이다.

빨간 코드 부분이 변경되어야 하는 부분이므로,

오른쪽 하얀 코드 상자처럼 바꾸면 코드를 바꿀 부분이 적어진다.

 

properties는 String,String 으로 저장되고

Map은 String,Object로 저장되기 때문에

이번에는 Map을 사용한다.


자동 import 하기


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

car=com.fastcampus.ch3.diCopy2.Truck
engine=com.fastcampus.ch3.diCopy2.Engine

 

실행 결과

 

위와 같이 하드코딩을 하면 좋지 않기 때문에

코드를 바꿔보자


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 사용하기

 

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);
    }
}

 

실행 결과

 

 

만약 클래스위에 어노테이션을 주석처리한다면

//@Component 
class Engine{}

 

Map에 저장되지 않아서

실행결과가 아래와 같이 나온다.


본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.

http://bit.ly/3Y34pE0

 

패스트캠퍼스 [직장인 실무교육]

프로그래밍, 영상편집, UX/UI, 마케팅, 데이터 분석, 엑셀강의, The RED, 국비지원, 기업교육, 서비스 제공.

fastcampus.co.kr

 

profile

Burninghering's Blog

@개발자 김혜린

안녕하세요! 반갑습니다.