클라리네
40
2019-07-30 11:41:43
6
242

스프링 controller 단에서 hashmap 객체 의존성 주입하여 사용하기


안녕하세요.

개발 하다가 궁금증이 생겨서 질문드립니다.


스프링 콘트롤러 단에서 hashmap을 사용할 때 메소드 안에서 "Map<String, Object> map = new HashMap<>();"을 해서 사용합니다.

구글링을 통해 찾은 코드에서 다 그렇게 사용하더군요.

잘 사용하다 의문점이 생겼습니다.

다른 bean들은 의존성 주입을 사용을 사용하는데 왜 hashmap은 의존성 주입을 하지 않을까하구요.


아래와 같이 말이요...

@Controller

@RequestMapping(value = "/bbs")

public class BbsFrontController {

    @Inject

    HashMap<String, Object> map;


    // 게시판그룹 수정

    @ResponseBody

    @RequestMapping(value = "/group/modify", method = RequestMethod.POST)

    public Map<String, Object> modifyGroup(@Valid BbsGroupVo vo, @Valid SqVo sqVo, Errors errors) {

//        Map<String, Object> map = new HashMap<>();

        map.clear();

        if (errors.hasErrors()) {

            map.put("msg", messageManager.getMessage("system.WrongAccess"));

            map.put("isSuccess", AJAX_FAIL);

            return map;

        }

        try {

            svc.modifyBbsGroupInfo(vo, Integer.parseInt(sqVo.getSq()));

            map.put("msg", messageManager.getMessage("board.ModifyGroupInfo"));

            map.put("isSuccess", AJAX_SUCCESS);

        } catch (Exception e) {

            e.printStackTrace();

            map.put("msg", messageManager.getMessage("board.ModifyGroupInfo.Fail"));

            map.put("isSuccess", AJAX_FAIL);

        }

        return map;

    }

}


혹시 관습인건지...아니면 의존성 주입이 불리한 부분이 있어서 "Map<String, Object> map = new HashMap<>();"를 사용하는 것인지 고견 부탁드립니다.

감사합니다.


0
0
  • 답변 6

  • 자라선
    1k
    2019-07-30 12:17:19 작성 2019-07-30 12:18:58 수정됨

    그냥 제 생각입니다.

    DI는 의존성 주입을 하기위한 오브젝트가 필요한데 스프링은 xml 을 표준으로 사용하고있죠.

    그럼 일일히 applicationContext.xml 에서 설정해주어야 하고 map을 저렇게 사용하면 다른 객체들도 똑같이 사용할테니 xml의 코드가 번잡해져 관리가 힘들겠죠(높은 결합도 이슈),

    또 모든 Controller에 저렇게 의존성 주입을 해주어 객체를 만들어준다면 스프링은 bean를 생성함과 동시에 싱글톤 레지스트리에 적재하여 사용하지 않는데도 불과하고 메모리에 상주하고있겠죠. (메모리 누수)


    그리고 구글링을 통해 사용하는 이유는 메소드에 해당 map를 휘발성 변수로 정의함으로써 메소드가 끝남과 동시에 메모리에서 빠져나오니 비교적 효율적이라 할수도 있겠네요.(라이프사이클)


    0
  • 클라리네
    40
    2019-07-30 12:32:59

    답변 감사합니다.

    역시 메모리 이슈군요.

    그냥 써야겠네요^^;

    0
  • 한판만
    437
    2019-07-30 13:02:55

    가비지 컬렉터가 사용하지 않으면 회수해가니 그런거 아닐까요?

    0
  • 클라리네
    40
    2019-07-30 15:28:33 작성 2019-07-30 15:30:37 수정됨

    위의 댓글 달고 한번 더 생각해보니 사실 이해가 안되는 부분은 있습니다..

    다른 클래스들은 의존성 주입해서 사용하면서 map만 그렇게 하지 않는다는건...그냥 그러려니 해야 할까봐요.

    자라선님과 한판만님 말씀대로라면 어짜피 가비지 컬렉터가 회수해 갈거니 의존성 주입할 이유가 없어지니까요.

    애초에 스프링의 xml을 이용하여 의존성 주입하는 방법은 싱글톤 인스턴스 방식으로 객체를 사용하기 위함이라고 알고 있습니다. 그것이 주는 이점이 map에는 통용이 안된다는 것이 조금 의아하네요. hashmap 하나 더 의존성 주입한다고 해서 xml이 더러워지고  메모리 누수를 염려할 정도는 아니라고 생각은 듭니다. 같은 이유로 의존성 주입한 객체들도 사용하지 않으면 메모리에 상주하고 있는 더미 객체일 뿐이라는 생각이네요.

    만약 그렇다면 외부 의존성 주입할 필요없이 그냥 new 키워드를 사용하여 객체를 사용하면 훨씬 xml이 깨끗해지고 코드 작성하기도 편할텐데요.


    처음 자라선님이 답변 주셨을땐 아...했으나 다시 생각해보니 그렇네요.

    댓글 방향이 좀 엇나간거 같습니다.

    왜 콘트롤러에서 map은 의존성 주입해서 사용하지 않을까요?

    명쾌한 답변은 없는걸까요..ㅠㅠ

    0
  • 자라선
    1k
    2019-07-30 15:47:59 작성 2019-07-30 15:53:39 수정됨

    @클라리네 

    가비지 컬렉터가 기억이 잘안는데 힙 메모리만 회수하는거 아니였나요?

    싱글톤으로 메모리 적재할땐 스택 메모리에 적재할텐데?

    안그러면 스프링이 돌아갈수가없죠 싱글톤 레지스트리에 빈 오브젝트를 생성하는데


    코딩에는 답이없습니다. 어떤 방식을 사용하거든 결과만 맞으면 성공한거죠.

    하지만 이런말이 있죠. 프로그래머는 컴퓨터가 이해할수 있는 언어가 아닌 사람이 이해할수 있는 언어를 짠다고...

    map을 올려도 상관은 없습니다.

    개인 프로젝트라면 상관이 없지만 확장성을 고려한 팀프로젝트라면 의미가 달라지겠죠.


    또 bean으로 올리면 보통 다른 오브젝트에서도 공용적으로 사용한다 볼수있습니다.

    해당 객체에서만 사용할려고 bean을 올리는게 아닐테니 

    다른 스레드와 map value 충돌이 이러나겠죠.

    이건 thread-safe 라고 검색하시면 좋을것 같습니다.


    좀 과장된 예시로 모든 컬렉션 리스트들 static으로 올리면 사용하기 편하겠지만

    하지않는 이유랑 비슷할거 같네요.

    0
  • 클라리네
    40
    2019-07-30 16:20:50 작성 2019-07-30 16:22:37 수정됨

    정확하게 이해됐습니다.

    가비지 컬렉터와 메모리 구조에 대해 다시 생각해보니 자라선님 말씀이 맞네요.

    이래서 기초가 중요합니다..ㅠㅠ

    답변 감사합니다.

    0
  • 로그인을 하시면 답변을 등록할 수 있습니다.