Spring DI 모방 – 객체 검색 방법 (by type/by name)

  • by


개체 찾기

1. 이름으로 검색 – Map의 Key로 검색 (오브젝트 주소를 돌려준다)

2. 유형으로 검색 – Map의 Value로 검색 (오브젝트 반환)

 Object getBean(String key){
        return map.get(key);
   } 
   
   //By Type 검색
   Object getBean(Class clazz) {
       for (Object obj : map.values()) { //map의 모든 value를 가져와서
           if (clazz.isInstance(obj)) //obj가 class의 객체거나 자손이면 true가 됨
               return obj;
       }
       return null;
   }

}

public class Main3 {
    public static void main(String() args) throws Exception {
        AppContext ac = new AppContext();
        Car car = (Car) ac.getBean("car"); //byName으로 객체를 검색
        Car car2 = (Car) ac.getBean(Car.class); //byType으로 객체를 검색
        Engine engine = (Engine) ac.getBean("engine"); 
        System.out.println("car = " + car);
        System.out.println("engine = " + engine);
    }
}




오브젝트 저장소에 세 개의 오브젝트가 저장될 때

첫 번째 노란색 상자는 수동으로 객체 참조를 연결합니다.

value 값을 iv에 저장하는 값

이렇게 수동으로 수행하는 대신

주석 달기 -> 객체 자동 연결

map에 저장된 객체를 찾아 자동으로 연결합니다.

(by Type에서 찾고)

리포지토리에 저장된 개체의 값을 지연시키고,

발견된 값을 참조 변수에 할당하는 것입니다.



By Name으로 검색하여 자동 연결하는 방법

by Name은 해당 키로 찾아 가치를 대입해 주는 것으로

by Type은 Value에서 instanceOf로 검색 -> 검색하여 참조 변수에 저장


@Component class Car{
    Engine engine; //iv
    Door door; //iv
}
public class Main4 {
    public static void main(String() args) throws Exception {
        AppContext ac = new AppContext(); //객체 저장소 만들기 

        Car car = (Car) ac.getBean("car"); //byName으로 객체를 검색
        Engine engine = (Engine) ac.getBean("engine");
        Door door = (Door) ac.getBean(Door.class); //byType으로 객체를 검색

        //수동으로 객체를 연결
        car.engine=engine;
        car.door=door;

        System.out.println("car = " + car);
        System.out.println("engine = " + engine);
        System.out.println("door = " + door);
    }
}


Car에 toString을 추가해 보겠습니다.

@Component class Car{
    Engine engine; //iv
    Door door; //iv

    @Override
    public String toString() {
        return "Car{" +
                "engine=" + engine +
                ", door=" + door +
                '}';
    }
}
public class Main4 {
    public static void main(String() args) throws Exception {
        AppContext ac = new AppContext(); //객체 저장소 만들기

        Car car = (Car) ac.getBean("car"); //byName으로 객체를 검색
        Engine engine = (Engine) ac.getBean("engine");
        Door door = (Door) ac.getBean(Door.class); //byType으로 객체를 검색

        //수동으로 객체를 연결
//        car.engine=engine;
//        car.door=door;

        System.out.println("car = " + car);
        System.out.println("engine = " + engine);
        System.out.println("door = " + door);
    }
}


수동으로 객체를 연결하는 부분을 주석 처리하므로,

Car의 IV가 null로 나온다.


@Autowired와 함께

doAutowired 메서드를 만들었습니다.

@Component class Car{
    @Autowired
    Engine engine; //iv
    @Autowired
    Door door; //iv

    @Override
    public String toString() {
        return "Car{" +
                "engine=" + engine +
                ", door=" + door +
                '}';
    }
}

   AppContext() {

        map = new HashMap();
        doComponentScan();
        doAutowired();
    }

    private void doAutowired(){
        //map에 저장된 객체의 iv 중에 @Autowired가 붙어있으면
        //map에서 iv의 타입에 맞는 객체를 찾아서 연결(객체의 주소를 iv에 저장한다는 뜻)
        try {
            for(Object bean: map.values()){
                for(Field fld:bean.getClass().getDeclaredFields()){
                    if(fld.getAnnotation(Autowired.class)!
=null){ //by Type fld.set(bean,getBean(fld.getType())); //car에 engine이 있으면 obj를 넣어주는 것이다 } } } } catch (IllegalAccessException e) { e.printStackTrace(); } }



@Resource 연습

@Component class Car{
    @Resource
    Engine engine; //iv
    @Resource
    Door door; //iv

    @Override
    public String toString() {
        return "Car{" +
                "engine=" + engine +
                ", door=" + door +
                '}';
    }
}
    AppContext() {

        map = new HashMap();
        doComponentScan();
        doAutowired();
        doResource();
    }

    private void doResource() {
        //map에 저장된 객체의 iv 중에 @Resource가 붙어있으면
        //map에서 iv의 이름에 맞는 객체를 찾아서 연결(객체의 주소를 iv에 저장한다는 뜻)
        try {
            for(Object bean: map.values()){
                for(Field fld:bean.getClass().getDeclaredFields()){
                    if(fld.getAnnotation(Resource.class)!
=null){ //by Name fld.set(bean,getBean(fld.getName())); //car에 engine이 있으면 obj를 넣어주는 것이다 } } } } catch (IllegalAccessException e) { e.printStackTrace(); } }