인프런 커뮤니티 질문&답변

maurizio님의 프로필 이미지
maurizio

작성한 질문수

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술

유연한 컨트롤러2 - v5

mappingMap과 inithandler 외부 주입에 대한 질문 드립니다.

작성

·

350

0

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.

1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)


2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)

 

3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)

[질문 내용]

강의 후반부에 외부에서 mappingMap과 adapters를 외부에서 주입 하는 방식으로 하는 이야기를 해주셔서 만들어봤는데 말씀하신 외부에서 주입한다는 방식이 맞는지 궁금해서 질문드립니다.


public class HandlerMapping implements initMyHandler{

    @Override
    public Map<String, Object> initHandlerMappingMap() {

        Map<String,Object> handlerMappingMap=new HashMap<>();
        handlerMappingMap.put("/front-controller/v5/v3/members/new-form", new MemberFormControllerV3());
        handlerMappingMap.put("/front-controller/v5/v3/members/save", new MemberSaveControllerV3());
        handlerMappingMap.put("/front-controller/v5/v3/members", new MemberListControllerV3());

        //V4 추가
        handlerMappingMap.put("/front-controller/v5/v4/members/new-form", new MemberFormControllerV4());
        handlerMappingMap.put("/front-controller/v5/v4/members/save", new MemberSaveControllerV4());
        handlerMappingMap.put("/front-controller/v5/v4/members", new MemberListControllerV4());


        return handlerMappingMap;
    }

    @Override
    public List<MyHandlerAdapter> initHandlerAdapters() {
        List<MyHandlerAdapter> handlerAdapters = new ArrayList<>();
        handlerAdapters.add(new ControllerV3HandlerAdapter());
        handlerAdapters.add(new ControllerV4HandlerAdapter());
        return handlerAdapters;
    }
}

이렇게 인터페이스를 구현하였고

 

frontControllerServlert 에는

 

private HandlerMapping handlerMapping=new HandlerMapping();

 

private Object getHandler(HttpServletRequest request) {
    String requestURI = request.getRequestURI();
    Map<String, Object> handlerMappingMap = handlerMapping.initHandlerMappingMap();
    return handlerMappingMap.get(requestURI);

}
private MyHandlerAdapter getHandlerAdapter(Object handler) {
    List<MyHandlerAdapter> myHandlerAdapters = handlerMapping.initHandlerAdapters();
    for (MyHandlerAdapter adapter : myHandlerAdapters) {
        //MemberFormControllerV3 (부모가 ControllerV3),MemberFormControllerV4 (부모가 ControllerV4)
        if (adapter.supports(handler)) {
           return adapter;
        }
    }
    throw new IllegalArgumentException("handler adapter를 찾을수 없습니다."+handler);
}

이렇게 동작하도록 하였는데 이것도 외부주입하는 방식으로 작성 했다고 볼수 있는지 궁금합니다.

 

답변 1

0

안녕하세요, 인프런 AI 인턴이에요.

주신 코드를 보면 HandlerMapping 클래스가 initMyHandler 인터페이스를 구현하고 있습니다. 이를 통해 initHandlerMappingMap() 메서드를 정의하고 있습니다.

initHandlerMappingMap() 메서드 안에서는 handlerMappingMap이라는 맵 객체를 생성하고 있습니다. 이 맵 객체에는 URL 패턴과 해당 패턴에 대한 처리기 객체를 매핑하는 역할을 합니다.

외부에서 mappingMap과 adapters를 주입하는 방식은 일반적으로 의존성 주입(Dependency Injection) 기법을 의미합니다. 의존성 주입이란 객체 간의 의존 관계를 코드 내에서 정의하지 않고 외부에서 주입받는 방식으로 처리하는 것을 의미합니다.

따라서, HandlerMapping 클래스에서 외부에서 mappingMap과 adapters를 주입받을 수 있도록 구현할 수 있습니다. 이를 위해 생성자나 setter 메서드를 통해 외부에서 이들을 주입받을 수 있도록 하면 됩니다.

예를 들어, 생성자를 통해 주입받는 방식이라면 아래와 같이 코드를 변경할 수 있습니다.

public class HandlerMapping implements initMyHandler{

    private Map<String,Object> mappingMap;
    private Map<String,Object> adapters;

    public HandlerMapping(Map<String,Object> mappingMap, Map<String,Object> adapters) {
        this.mappingMap = mappingMap;
        this.adapters = adapters;
    }

    @Override
    public Map<String, Object> initHandlerMappingMap() {
        // mappingMap과 adapters를 사용하여 맵핑 작업 수행
        // ...
        return handlerMappingMap;
    }
}

위의 코드처럼 생성자를 통해 외부에서 mappingMap과 adapters를 주입받고, initHandlerMappingMap() 메서드 안에서 주입받은 객체들을 사용하여 맵핑 작업을 수행하면 외부에서 주입받아 사용하는 방식으로 구현할 수 있습니다.

질문이 맞는지 확인해보셨나요? 추가적으로 질문이 있다면 말씀해주세요.

maurizio님의 프로필 이미지
maurizio
질문자

안녕하세요 답변 감사 드립니다. 다시 한번 설명 드리겠습니다 아직 모르는것이 많아서 답변 주신 내용과 제가 질문 드린 내용이 동일한가 헷갈려서 다시 한번 설명 드리겠습니다.

해당 부분은 설정하는 클래스 라고 정하겠습니다.

public class HandlerMapping implements initMyHandler{
    Map<String,Object> handlerMappingMap=new HashMap<>();
    List<MyHandlerAdapter> handlerAdapters = new ArrayList<>();
    @Override
    public Map<String, Object> initHandlerMappingMap() {
        handlerMappingMap.put("/front-controller/v5/v3/members/new-form", new MemberFormControllerV3());
        handlerMappingMap.put("/front-controller/v5/v3/members/save", new MemberSaveControllerV3());
        handlerMappingMap.put("/front-controller/v5/v3/members", new MemberListControllerV3());
        //V4 추가
        handlerMappingMap.put("/front-controller/v5/v4/members/new-form", new MemberFormControllerV4());
        handlerMappingMap.put("/front-controller/v5/v4/members/save", new MemberSaveControllerV4());
        handlerMappingMap.put("/front-controller/v5/v4/members", new MemberListControllerV4());
        return handlerMappingMap;
    }

    @Override
    public List<MyHandlerAdapter> initHandlerAdapters() {
        handlerAdapters.add(new ControllerV3HandlerAdapter());
        handlerAdapters.add(new ControllerV4HandlerAdapter());
        return handlerAdapters;
    }
}

 

그리고

@Bean
public initMyHandler initMyHandler(){
   return new HandlerMapping();
}
빈으로 등록하였습니다.

 

그리고 프론트컨트롤러에서

 


 private final initMyHandler handlerMapping;

    public FrontControllerServletV5(initMyHandler handlerMapping) {
        this.handlerMapping = handlerMapping;
    }

이렇게 생성자 주입 후


    private Object getHandler(HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        Map<String, Object> handlerMappingMap = handlerMapping.initHandlerMappingMap();
        return handlerMappingMap.get(requestURI);

    }


명칭등이 조금 꼬였는데  
기존에 핸들러매핑맵, 핸들러어댑터를  설정클래스로 지정하여 빈으로 등록하고
해당 빈을 생성자주입으로 사용한다고 생각하고 만들었는데  이게 외부주입이 맞는지 궁금합니다. 
maurizio님의 프로필 이미지
maurizio

작성한 질문수

질문하기