jykwak84
141
2014-03-26 12:45:34
3
11739

스프링에서 contextConfigLocation 질문좀..


이제 막 스프링 입문한 개발자인데여
이번에 스프링시큐리티를 쓰고 있습니당
sts에서 스프링템플릿 프로젝트로 만들고 있는데

web.xml에


contextConfigLocation

/WEB-INF/spring/root-context.xml
/WEB-INF/spring/spring-security-context.xml




org.springframework.web.context.ContextLoaderListener



appServlet
org.springframework.web.servlet.DispatcherServlet

contextConfigLocation
/WEB-INF/spring/appServlet/servlet-context.xml

1

..중략

대략 이런식으로 되어 있고
servlet-context.xml에


이렇게 컴포넌트 스캔을 걸어놨는데..
spring-security-context.xml 파일에










가 있는데 testUserService 빈 구현클래스인 TestService.java에서
동일 패키지에 있는 다른 bean객체들을 못가져 오더라구여. 그래서
spring-security-context.xml 파일안에

선언하니 빈들을 잘 가져오더라구요.
근데 이렇게 되면



을 선언한 소스가
spring-security-context.xml와
servlet-context.xml이렇게 두개파일에 각각 있어서 별로 마음에는
안들더라구요. 그렇다구
servlet-context.xml에서 컴포넌트 스캔을 빼면 막 404에러 나고
그런던데..
또 같은 contextConfigLocation로 설정한
root-context.xml에 컴포넌트 스캔을 걸었더니
spring-security-context.xml에는 컴포넌트 스캔을 안걸어도
TestService.java에서 빈들을 잘 찾을수 있었습니다.
글이 우왕좌왕 길어졌는데 질문의 요지는..

1) contextConfigLocation과 DispatcherServlet의 관계
2) 을 한번만 써서
3개의 xml에 다 적용되는 방법??이 궁금합니당..
여러곳 검색하다가 아직 이해가 덜 되어서 질문드립니다.
알려주세용.
0
  • 답변 3

  • 커비
    2k
    2014-03-26 13:21:43
    1. 질문이 이상한데 ContextLoaderListener 과 DispatcherServlet 의 관계라고 하시는게 맞는것 같네요.
    상단에

    contextConfigLocation

    /WEB-INF/spring/root-context.xml
    /WEB-INF/spring/spring-security-context.xml

    부분 설정은 ContextLoaderListener 의 설정 부분입니다.

    아래쪽

    contextConfigLocation
    /WEB-INF/spring/appServlet/servlet-context.xml

    설정은 DispatcherServlet의 설정 부분이구요

    이제 답변드리면 위와 같은 설정으로 스프링(보통 MVC) 사용할 때 보통 사용하게 되는 설정입니다.

    위와 같은 설정의 의미는 스프링이 bean을 관리하는데 두개의 컨테이너를 사용한다는 뜻입니다.

    보통 전자는 Root Web ApplicationContext(이하 RooWAC)라 부르구요 뒤에는 보통 WebApplicationContext(이하 WAC)라 부릅니다. 토비님 블로그 참조 ( http://toby.epril.com/?p=934 )
    Bean을 관리하는 두개의 컨텍스트가 올라가 있습니다.

    해당 설정별로 독자적으로 Bean을 관리하기 때문에 처음 접근 할 때는 헷갈리는 경우도 좀있습니다.
    일단 두개로 되어 있지만 RootWAC과 그냥 WAC은 부모 자식 관계라 RootWAC에서 설정된 Bean은 WAC에서 가져와서 사용할 수 있습니다. 문제는 그 반대의 경우는 안된다는 겁니다.
    그래서 좀 신경써줘야 되는 부분입니다.

    일단 1번 문제에 대한 답변은 된 것 같군요

    2번은 사실 문제가 되는 경우는 둘다 동일한 위치에서 Bean을 스캔한다고 생각해보시면 1번에서 설명한 것을 이해 하셨으면 뭐가 문제 인지 바로 생각 나실거에요.
    동인할 Class가 RootWAC에도 있고 WAC에도 있으면 문제가 생길 수도 있으니 주의 하세요

    3번 1번의 내용을 이해 하셨으면 당연히 RootWAC에서만 Bean을 올리게 되면 WAC에서도 적용이 되겠죠?

    여기서 주의 해야 될점은 @Controller 같은 경우 웹의 요청을 받는 부분입니다.
    이부분은 반드시 WAC에서만 하셔야 됩니다.
    그러니 해당 부분을 아무리 RootWAC에서 스캔을 하여 Bean을 생성 해봐도 웹요청이 오면 해당 @Controller에서 못받습니다!!

    이 @Controller 이부분만은 반드시 RootWAC에서 가져와야합니다.


    정리 하자만 공통으로 쓸 Bean은 RootWAC부분에서 설정 해둔다.
    Web과 관계된 Bean은 WAC부분으로 설정해둔다.
    이렇게 정리가 되겠네요.

    방법은 component-scan부분을 범위를 좁하는 겁니다.

    WebController있는 부분만 Scan할 수 있도록 패키지를 좁혀주세요.

    RootWAC 설정 부분은

    WAC 설정 부분은
    example)

    만약에 패키지 별로 구분되어 있지 않으면 component-sacn 옵션에서 어노테이션 또는 클래스 명으로 필터링이 가능하니 그것까지는 설명 안드리겠습니다.

    즐거운 스프링 프로그래밍 되시길~
  • daejoon
    246
    2014-03-26 14:41:29
    저도 그런 경우가 있는데 아래와 같이 해결했습니다.

    http://ddoong2.com/946
  • jykwak84
    141
    2014-03-26 16:27:25
    두분다 감사합니다. 이해도 되고 해결도 봤습니당 ㅎ
  • 로그인을 하시면 답변을 등록할 수 있습니다.