IT TIP

Spring : web.xml의 네임 스페이스 대 contextConfigLocation 초기화 매개 변수

itqueen 2020. 12. 13. 11:35
반응형

Spring : web.xml의 네임 스페이스 대 contextConfigLocation 초기화 매개 변수


Spring MVC에 대한 문서를 읽고 있는데 init 매개 변수에 대한 질문이 있습니다. 중요한 경우 Spring 3.2를 사용하고 있습니다. contextConfigLocation과 네임 스페이스의 차이점은 무엇입니까? contextConfigLocation은 컨텍스트 클래스가 XML 정의를 찾을 수있는 폴더를 지정하기위한 것이고 네임 스페이스 속성은 파일 이름을 지정하기위한 것입니까?

<servlet>
        <servlet-name>AppServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF</param-value>
        </init-param>
        <init-param>
            <param-name>namespace</param-name>
            <param-value>application-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

이 올바른지? /WEB-INF/application-context.xml을 사용해야합니까? 그리고 경로를 지정해야합니까?


TL; DR

contextConfigLocation사용자 정의 구성 파일을 지정해야 할 때마다 값을 설정하십시오. 이렇게하면 구성 파일 이름과 위치를 모두 지정할 수 있습니다.

이것은 namespace본질적으로 Spring 컨테이너 컨텍스트 로더 클래스에게 사용할 구성 파일을 알려주 는 대체 방법 입니다. 나는 그것에 대해 결코 신경 쓰지 않지만 contextConfigLocation사용자 지정 구성 파일을 구성해야 할 때마다 사용 합니다.

다음은 이전 Spring 프로젝트 중 하나의 예입니다 (간결성을 위해 일부 구성은 생략 됨).

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                            http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <display-name>Spring Web Application example</display-name>

    <!-- Configurations for the root application context (parent context) -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring/jdbc/spring-jdbc.xml
            /WEB-INF/spring/security/spring-security-context.xml
        </param-value>
    </context-param>

    <!-- Configurations for the DispatcherServlet application context (child context) -->
    <servlet>
        <servlet-name>spring-mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                /WEB-INF/spring/mvc/spring-mvc-servlet.xml
            </param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring-mvc</servlet-name>
        <url-pattern>/admin/*</url-pattern>
    </servlet-mapping>

</web-app>

긴 대답

좋아, 먼저 중요한 순간을 명확히하자. 우리가 다루는 두 가지 유형의 컨텍스트가 있습니다.

  1. 루트 컨텍스트 (상위)
  2. 개별 서블릿 컨텍스트 (하위)

WebApplicationContext (강조 내)에 대한 Spring Framework API (이 글을 쓰는 시점의 버전 3.2.2)에서 인용하십시오 .

일반 애플리케이션 컨텍스트와 마찬가지로 웹 애플리케이션 컨텍스트는 계층 적입니다. 애플리케이션 당 단일 루트 컨텍스트가있는 반면 애플리케이션의 각 서블릿 (MVC 프레임 워크의 디스패처 서블릿 포함)에는 자체 자식 컨텍스트가 있습니다.

또한 여기에 : 컨텍스트 계층 :

예를 들어 Spring MVC 웹 애플리케이션을 개발하는 경우 일반적으로 Spring의 ContextLoaderListener를 통해로드 된 루트 WebApplicationContextSpring의 DispatcherServlet을 통해로드 된 자식 WebApplicationContext가 있습니다. 그 결과 공유 구성 요소 및 인프라 구성이 루트 컨텍스트에서 선언되고 웹 특정 구성 요소에 의해 자식 컨텍스트에서 사용되는 부모-자식 컨텍스트 계층이 생성됩니다.

그리고 여기 : 17.2 DispatcherServlet :

Spring의 ApplicationContext 인스턴스는 범위를 지정할 수 있습니다. Web MVC 프레임 워크에서 각 DispatcherServlet에는 루트 WebApplicationContext에 이미 정의 된 모든 빈을 상속하는 자체 WebApplicationContext가 있습니다. 이러한 상속 된 빈은 서블릿 특정 범위에서 재정의 될 수 있으며 주어진 서블릿 인스턴스에 로컬로 새로운 범위 특정 빈을 정의 할 수 있습니다.


이제 루트 애플리케이션 컨텍스트 구성을 살펴 보겠습니다 . 예 :
web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                            http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/spring/daoContext.xml
            /WEB-INF/spring/applicationContext.xml
        </param-value>
    </context-param>
</web-app>


공식 Spring 문서 (강조 내)에서 :
5.14.4 웹 애플리케이션을위한 편리한 ApplicationContext 인스턴스화 :

예를 들어 ContextLoader를 사용하여 ApplicationContext 인스턴스를 선언적 으로 만들 수 있습니다 . 물론 ApplicationContext 구현 중 하나를 사용하여 프로그래밍 방식으로 ApplicationContext 인스턴스를 만들 수도 있습니다.

ContextLoaderListener를 사용하여 ApplicationContext를 등록 할 수 있습니다 (위의 예 참조).

리스너는 contextConfigLocation 매개 변수를 검사합니다. 매개 변수가없는 경우 리스너는 /WEB-INF/applicationContext.xml을 기본값으로 사용 합니다. 매개 변수가 존재하면 리스너는 미리 정의 된 구분 기호 (쉼표, 세미콜론 및 공백)를 사용하여 문자열을 구분하고 값을 응용 프로그램 컨텍스트가 검색 될 위치로 사용합니다. Ant 스타일 경로 패턴도 지원됩니다. 예를 들면 이름이 "Context.xml"로 끝나고 "WEB-INF"디렉토리에있는 모든 파일에 대한 /WEB-INF/*Context.xml 및 모두에 대해 /WEB-INF/**/*Context.xml입니다. "WEB-INF"의 하위 디렉토리에있는 이러한 파일.


꽤 자주 Spring 구성은 여러 파일로 분할됩니다. 특히 대규모 프로젝트에서 더 논리적이고 편리합니다. 이 예에서는 사용자 지정 위치에 daoContext.xmlapplicationContext.xml 이라는 두 가지 구성 XML 파일을 명시 적으로 정의했습니다 /WEB-INF/spring/. 다시 말하지만, 우리는 정의되어 있지 있었다 는 contextConfigLocation을의 ContextLoaderListener는 기본 설정 파일을 찾으려고합니다 : /WEB-INF/applicationContext.xml.

참고 : 루트 컨텍스트는 선택 사항입니다 . 이 답변도 참조하십시오 : https://stackoverflow.com/a/7451389/814702

따라서 기본 /WEB-INF/applicationContext.xml구성 파일이 필요에 맞지 않으면 ContextLoaderListener<context-param> contextConfigLocation 과 함께 사용 하여 루트 응용 프로그램 컨텍스트를 정의하기 위해 사용자 정의 구성 파일을 정의 할 수 있습니다 .


다음으로 개별 (자식) 애플리케이션 컨텍스트를 살펴 보겠습니다 . 공식 Spring 문서에서 (강조 내) :
17.2 The DispatcherServlet

DispatcherServlet 초기화시 Spring MVC는
웹 애플리케이션 의 WEB-INF 디렉토리에서 [servlet-name] -servlet.xml 이라는 파일을 찾고 거기에 정의 된 Bean을 생성하여 동일한 이름으로 정의 된 Bean의 정의를 재정의합니다. 글로벌 범위에서.

다음 DispatcherServlet Servlet 구성을 고려하십시오 (web.xml 파일에서).

<web-app>

    <servlet>
        <servlet-name>golfing</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>golfing</servlet-name>
        <url-pattern>/golfing/*</url-pattern>
    </servlet-mapping>

</web-app>


contextConfigLocation 및 네임 스페이스 정보

문서에서 (강조 내) :

위의 서블릿 구성을 사용하면
/WEB-INF/golfing-servlet.xml애플리케이션에서 호출 파일이 있어야 합니다. 이 파일에는 모든 Spring Web MVC 관련 구성 요소 (빈)가 포함됩니다. Servlet 초기화 매개 변수를 통해이 구성 파일의 정확한 위치를 변경할 수 있습니다 (자세한 내용은 아래 참조).
... Servlet 초기화 매개 변수 (init-param 요소)를 web.xml 파일의 Servlet 선언에 추가하여
개별 DispatcherServlet 인스턴스사용자 정의 할 수 있습니다 . 지원되는 매개 변수 목록은 다음 표를 참조하십시오.

  • contextClass :이 서블릿이 사용하는 컨텍스트를 인스턴스화하는 WebApplicationContext를 구현하는 클래스. 기본적으로 XmlWebApplicationContext가 사용됩니다.

  • contextConfigLocation : 컨텍스트를 찾을 수있는 위치를 나타 내기 위해 컨텍스트 인스턴스 (contextClass에 의해 지정됨)에 전달되는 문자열입니다. 문자열은 여러 컨텍스트를 지원하기 위해 잠재적으로 여러 문자열 (쉼표를 구분 기호로 사용)로 구성됩니다. 빈이 두 번 정의 된 여러 컨텍스트 위치의 경우 최신 위치가 우선합니다.

  • namespace : WebApplicationContext의 네임 스페이스입니다. 기본값은 [servlet-name] -servlet입니다.


이제 관련 클래스에 대한 API 문서를 조사해 보겠습니다. DispatcherServlet 클래스는 추상 클래스 FrameworkServlet을 확장 합니다. 로부터 FrameworkServlet의 API 문서 (강조 광산) :

"contextConfigLocation"서블릿 init-param을 컨텍스트 인스턴스에 전달하여
"test-servlet.xml, myServlet.xml" 과 같이 쉼표와 공백으로 구분 될 수있는 잠재적으로 여러 파일 경로로 구문 분석합니다 . 명시 적으로 지정되지 않은 경우 컨텍스트 구현은 서블릿의 네임 스페이스에서 기본 위치를 빌드해야합니다 .

기본 네임 스페이스는 " 'servlet-name'-servlet"입니다. 예를 들어 servlet-name "test"의 경우 "test-servlet"(XmlWebApplicationContext가있는 "/WEB-INF/test-servlet.xml"기본 위치로 이어짐)이 있습니다. 네임 스페이스는 "namespace"서블릿 init-param을 통해 명시 적으로 설정할 수도 있습니다 .

다음은 FrameworkServlet 소스 코드 에서 발췌 한 것입니다 .
FrameworkServlet.java

....
/**
* Suffix for WebApplicationContext namespaces. If a servlet of this class is
* given the name "test" in a context, the namespace used by the servlet will
* resolve to "test-servlet".
*/
public static final String DEFAULT_NAMESPACE_SUFFIX = "-servlet";
....


FrameworkServlet 의 기본 컨텍스트 클래스 XmlWebApplicationContext 입니다. 로부터 XmlWebApplicationContext이의 API 문서 (강조 광산) :

기본적으로 구성은 루트 컨텍스트의 경우 "/WEB-INF/applicationContext.xml"에서 가져오고 네임 스페이스가 "test-servlet"인 컨텍스트의 경우 "/WEB-INF/test-servlet.xml"에서 가져옵니다 (예 : 서블릿 이름이 "test"인 DispatcherServlet 인스턴스의 경우).

구성 위치 기본값은 ContextLoader의 "contextConfigLocation"컨텍스트 매개 변수 및 FrameworkServlet의 서블릿 init-param을 통해 재정의 할 수 있습니다 . 구성 위치는 "/WEB-INF/context.xml"과 같은 구체적인 파일 또는 "/WEB-INF/*-context.xml"과 같은 Ant 스타일 패턴을 나타낼 수 있습니다 (패턴 세부 사항은 PathMatcher javadoc 참조).

를 사용하여 기본 구성 위치를 재정의 contextConfigLocation하는 것은 루트 애플리케이션 컨텍스트에 대한 위의 예에서와 동일합니다.

에 관해서는 재정의 기본 네임 스페이스 몇 가지 중요한 순간이있다. 새 네임 스페이스를 설정할 때 앞에 /WEB-INF추가 .xml하거나 추가하지 마세요 . 그 이유는 XmlWebApplicationContext 클래스 의 소스 파일을 보면 알 수 있습니다 :
XmlWebApplicationContext.java

...

/** Default config location for the root context */
public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";

/** Default prefix for building a config location for a namespace */
public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";

/** Default suffix for building a config location for a namespace */
public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";

...

/**
* The default location for the root context is "/WEB-INF/applicationContext.xml",
* and "/WEB-INF/test-servlet.xml" for a context with the namespace "test-servlet"
* (like for a DispatcherServlet instance with the servlet-name "test").
*/
@Override
protected String[] getDefaultConfigLocations() {
    if (getNamespace() != null) {
        return new String[] {DEFAULT_CONFIG_LOCATION_PREFIX + getNamespace() + DEFAULT_CONFIG_LOCATION_SUFFIX};
    }
    else {
        return new String[] {DEFAULT_CONFIG_LOCATION};
    }
}

보시다시피 소스 코드에 모든 것이 나와 있습니다.


사용자 정의 네임 스페이스 지정의 예

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                            http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">


    <!-- Configurations for the DispatcherServlet application context (child context) -->
    <servlet>
        <servlet-name>spring-mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>namespace</param-name>
            <param-value>spring/mvc/spring-mvc</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>spring-mvc</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

</web-app>

그 결과 구성 파일에 대한 경로를 구성하는 데 기본 네임 스페이스를 사용하는 대신 /WEB-INF/spring-mvc-servlet.xml, 컨테이너가 /WEB-INF/spring/mvc/spring-mvc.xml.

NOTE:
The above explanations related to the setting custom namespace are for the default XmlWebApplicationContext context class. One can specify an alternative class, like AnnotationConfigWebApplicationContext, so there will be some special moments for that.


CONCLUSION

It is (IMHO) much more easier to use contextConfigLocation parameter to define custom config files, both for the root application context and for the individual contexts. The only difference is that for the root application context you use <context-param> within <web-app> element, but NOT within a specific servlet (also don't forget the listener class). And for the child context you use <init-param> nested inside the <servlet> element for each specific servlet. See my example configurations (web.xml) in the very beginning of this post.

Additional resources (as if the above was not enough :-)):


I think LuckyLuke's answer has a lot of useful info, but it doesn't answer the question. In particular, how "namespace" and "contextConfigLocation" parameters work together?

The only place I could find the concrete answer is the source code:

  • namespace paremeter sets a custom namespace to be used for building a default context config location
  • contextConfigLocation parameter sets the context config location explicitly, instead of relying on the default location built from the namespace

What is the difference between the contextConfigLocation and namespace? contextConfigLocation is used to specify the path of spring config files, that means they'll be initialized. namespace is used to specify the path and name of the DispatcherServlet of Spring MVC. default is [Dispatcher_name]-servlet.xml, here is an example:

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>namespace</param-name>
        <param-value>config/spring-mvc</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

Spring will search a file to be used as it's mvc config by the path of /WEB-INF/config/spring-mvc.xml.
Is the contextConfigLocation meant only for specifying the folders where the context class can find a XML definition

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/config/app-*.xml</param-value>
</context-param>

The code above showed that when application starting Spring will load all the the files which name starts with 'app-' and ends with '.xml' in the WEB-INF/config directory.

Should it use /WEB-INF/application-context.xml? And should you specify paths?
Through the example all above we can know that when configurating Spring we need to specify the full path and generic file name and when SpringMVC only we should specify the path(if it's located in a directory, not include the WEB-INF directory) and name(not include the extension).
Hope to help you:)

참고URL : https://stackoverflow.com/questions/15818047/spring-namespace-vs-contextconfiglocation-init-parameters-in-web-xml

반응형