Spring Framework에서 applicationContext.xml과 spring-servlet.xml의 차이점


373
  • 아르 applicationContext.xmlspring-servlet.xml스프링 프레임 워크에 여하튼 관련?
  • 속성 파일이 선언됩니까? applicationContext.xml 사용할 수 DispatcherServlet있습니까?
  • 관련 메모에서 왜 전혀 필요 *-servlet.xml합니까? applicationContext.xml혼자서 부족한 이유는 무엇 입니까?

1
이것도 참조하십시오. stackoverflow.com/questions/11708967/…
이상현

답변:


430

Spring을 사용하면 부모-자식 계층에서 여러 컨텍스트를 정의 할 수 있습니다.

applicationContext.xml즉, 웹 애플리케이션에 연결된 컨텍스트 "루트 웹 애플리케이션 컨텍스트"의 콩을 정의합니다.

spring-servlet.xml(또는 어떤 다른 당신이 그것을 호출) 하나의 서블릿의 응용 프로그램 컨텍스트의 빈을 정의합니다. 웹 애플리케이션에는 Spring 서블릿 당 하나씩 (예 : spring1-servlet.xmlservlet spring1, spring2-servlet.xmlservlet spring2) 여러 개가있을 수 있습니다 .

의 Bean은에서 Bean을 spring-servlet.xml참조 할 수 applicationContext.xml있지만 반대의 경우는 아닙니다.

모든 Spring MVC 컨트롤러는 spring-servlet.xml컨텍스트에 있어야합니다 .

가장 간단한 경우에는 applicationContext.xml컨텍스트가 필요하지 않습니다. 일반적으로 웹 애플리케이션의 모든 서블릿간에 공유되는 Bean을 포함하는 데 사용됩니다. 하나의 서블릿 만 가지고 있다면, 특별한 용도가 없다면 실제로는 아무 의미가 없습니다.


30
왜 여러 개의 스프링 서블릿이 있습니까?
NimChimpsky

5
(때문에 간결의) 강력한 강력한 대답
amphibient

35
@NimChimpsky 때로는 동일한 컨텍스트에서 충돌 할 수있는 응용 프로그램의 일부를 분리하는 것이 유용합니다. 예를 들어 ReST 서비스 및 표준보기가있을 수 있으며,보기와 관련하여 서비스에 대해 다른보기 확인자 또는 보안 문제가있을 수 있습니다.
Brett Ryan

12
사람들은 설명서를 읽고 앱을 개발하기 전에이 답변을 봐야합니다! 일반적인 경우에는 ContextLoaderListener 및 contextConfigLocation이 전혀 필요하지 않으며 DispatcherServlet 만 있으면됩니다!
ruruskyi

24
많은 자습서에서 contextConfigLocation에는 DispatcherServlet뿐만 아니라 dispatcher-servlet.xml이 포함됩니다. 이로 인해 Bean이 두 번 초기화됩니다!
ruruskyi

106

시나리오 1

클라이언트 애플리케이션에서 (애플리케이션은 웹 애플리케이션이 아니므로 스윙 앱일 수 있음)

private static ApplicationContext context = new  ClassPathXmlApplicationContext("test-client.xml");

context.getBean(name);

web.xml이 필요하지 않습니다 . Bean 서비스를 얻기위한 컨테이너로서의 ApplicationContext 웹 서버 컨테이너가 필요 없습니다. 에서 테스트-client.xml 없이 원격으로 간단한 콩, 리모팅과 콩있을 수 있습니다.

결론 : 시나리오 1에서 applicationContext와 DispatcherServlet관련이 없습니다.

시나리오 2

서버 응용 프로그램 (예 : Tomcat과 같은 서버에 배포 된 응용 프로그램) 클라이언트 프로그램 (예 : Swing 앱)에서 원격으로 서비스에 액세스

web.xml 에서 리스너 정의

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

서버 시작시 applicationContext.xml에ContextLoaderListener 정의 된 Bean을 인스턴스화 합니다 .

applicationContext.xml에 다음을 정의했다고 가정합니다 .

<import resource="test1.xml" />
<import resource="test2.xml" />
<import resource="test3.xml" />
<import resource="test4.xml" />

Bean은 네 가지 구성 파일 test1.xml , test2.xml , test3.xml , test4.xml 에서 인스턴스화 됩니다.

결론 : 시나리오 2에서 applicationContext와 DispatcherServlet관련이 없습니다.

시나리오 3

스프링 MVC가있는 웹 애플리케이션에서.

에서 web.xml의 정의 :

<servlet>
    <servlet-name>springweb</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>    
</servlet>

<servlet-mapping>
    <servlet-name>springweb</servlet-name>
    <url-pattern>*.action</url-pattern>
</servlet-mapping>

Tomcat이 시작되면 springweb-servlet.xml에 정의 된 Bean 이 인스턴스화됩니다. DispatcherServlet확장 FrameworkServlet합니다. 에서 FrameworkServlet빈 인스턴스는 DispatcherServlet은 위해 발생합니다. 우리의 경우 springweb 은 FrameworkServlet입니다.

결론 : 시나리오 3에서 applicationContext와 DispatcherServlet관련이 없습니다.

시나리오 4

스프링 MVC를 이용한 웹 애플리케이션. 서블릿 용 springweb-servlet.xml 및 서버 프로그램 내에서 비즈니스 서비스에 액세스하거나 다른 서버 프로그램에서 DB 서비스에 액세스하기위한 applicationContext.xml .

에서 web.xml에 다음이 정의된다 :

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
    <servlet-name>springweb</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>        
</servlet>

<servlet-mapping>
    <servlet-name>springweb</servlet-name>
    <url-pattern>*.action</url-pattern>
</servlet-mapping>

서버 시작시 applicationContext.xml에ContextLoaderListener 정의 된 Bean을 인스턴스화 합니다 . 당신이 여기에 선언했다고 가정 :

<import resource="test1.xml" />
<import resource="test2.xml" />
<import resource="test3.xml" />
<import resource="test4.xml" />

Bean은 모두 네 가지 test1.xml , test2.xml , test3.xml , test4.xml 에서 인스턴스화 됩니다. applicationContext.xml에 정의 된 Bean 인스턴스화가 완료된 후 springweb-servlet.xml에 정의 된 Bean 이 인스턴스화됩니다.

따라서 인스턴스화 순서는 루트 (응용 프로그램 컨텍스트)와 FrameworkServlet입니다.

이제 어떤 시나리오에서 왜 중요한지 분명해야합니다.


10
+1. 나는이 유형의 비교를 찾고 있었지만 결코 찾지 못했다.
Ninad Pingale

@abishkar bhattarai 아주 좋은, 내 질문은 : "시나리오 4"시 @ 구성 요소 및 @ 값 주석을 사용하여 빈을 만드는 경우 무엇입니까
Lawrence

DispatcherServletURL이 .action으로 끝나지 않으면 springweb 이 호출되지 않습니까?
Asif Mushtaq

@lawrence Spring이 스캔에서 해당 컴포넌트를 찾을 수 있도록 springweb-servlet.xml에 클래스 경로를 지정해야한다.
베리타스

54

하나 더 추가하고 싶습니다. 여기 spring-servlet.xml에는 Controller 패키지에 대한 구성 요소 스캔이 포함됩니다. 다음 예에서는 컨트롤러 패키지에 대한 필터 주석을 포함합니다.

<!-- Scans for annotated @Controllers in the classpath -->
<context:component-scan base-package="org.test.web" use-default-filters="false">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

에서 applicationcontext.xml우리 컨트롤러를 제외한 패키지를 나머지에 대한 필터를 추가합니다.

<context:component-scan base-package="org.test">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

9
왜 ? 왜 모든 것을 한 번만 스캔하지 않습니까?
NimChimpsky

3
@NimChimpsky @Controller서블릿 컨텍스트에서 Bean 을 스캔 해야합니다 (Spring MVC에 필요).
Tuukka Mustonen

3
왜 모든 것을 두 번 할 수 없습니까? 왜 포함 / 제외합니까?
마이크 Rylander

8
또한 spring-servlet.xml에 use-default-filters = "false"속성을 추가해야합니다
Rakesh Waghela

4
Rakesh Waghela는 지적했다. 이 속성이 없으면 Controller Bean이 두 번 생성됩니다. 첫 번째는 appContext, 두 번째는 servletContext
UltraMaster

12

간단히 말해서

applicationContext.xml모든 서블릿간에 공유되는 Bean을 정의합니다. 응용 프로그램에 둘 이상의 서블릿이있는 경우 공통 자원을 정의하는 것이 applicationContext.xml더 합리적입니다.

spring-servlet.xml해당 서블릿에만 관련된 Bean을 정의합니다. 여기 디스패처 서블릿이 있습니다. 따라서 Spring MVC 컨트롤러는이 파일에서 정의해야합니다.

spring-servlet.xml웹 애플리케이션에서 하나의 서블릿 만 실행중인 경우 모든 Bean을 정의하는 데 아무런 문제가 없습니다 .


3
spring-servlet.xml에 모든 Bean을 정의 할 수 있지만이 경우 빈이 없을 수있는 applicationContext.xml도 있어야합니다. 옳은?
Mikhail Kopylov

6

서블릿 기술에서 입력을 특정 서블릿에 전달하려면 아래 코드와 같이 init 매개 변수를 전달해야합니다.

 <servlet>
    <servlet-name>DBController</servlet-name>
    <servlet-class>com.test.controller.DBController</servlet-class>
    <init-param>
        <param-name>username</param-name>
        <param-value>John</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>DBController</servlet-name>
    <url-pattern>/DBController</url-pattern>
</servlet-mapping>

모든 서블릿에 공통적 인 입력을 전달하려면 컨텍스트 매개 변수를 구성해야합니다. 예

 <context-param>
    <param-name>email</param-name>
    <param-value>admin@example.com</param-value>
</context-param>

Spring MVC로 작업 할 때 정확히 이와 같이 Spring에서 제공하는 미리 정의 된 서블릿에 init 매개 변수를 통해 DispatcherServlet 인 정보를 제공해야합니다. 따라서 구성은 다음과 같습니다. 여기에서 DispatcherServlet에 spring-servlet.xml을 초기화 매개 변수로 제공합니다.

 <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
              http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <display-name>Spring MVC App</display-name>

    <servlet>
        <servlet-name>SpringController</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>SpringController</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>
</web-app>

다시 한 번 문맥 매개 변수가 필요합니다. 그것은 전체 응용 프로그램에 적용됩니다. 따라서 applicationcontext.xml 인 루트 컨텍스트를 제공 할 수 있습니다. 구성은 다음과 같습니다.

    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationcontext.xml</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
        <servlet-name>SpringController</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>SpringController</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>

4

응용 프로그램 컨텍스트는 해당 메시지의 i18n 지원을 포함하여 문자 메시지를 해결하는 수단을 제공합니다. 응용 프로그램 컨텍스트는 이미지와 같은 파일 리소스를로드하는 일반적인 방법을 제공합니다. 애플리케이션 컨텍스트는 리스너로 등록 된 Bean에 이벤트를 공개 할 수 있습니다. 빈 팩토리를 사용하여 프로그래밍 방식으로 처리해야하는 컨테이너 또는 컨테이너의 Bean에 대한 특정 조작은 애플리케이션 컨텍스트에서 선언적으로 처리 할 수 ​​있습니다. ResourceLoader 지원 : Spring의 Resource 인터페이스는 저수준 리소스를 처리하기위한 유연한 일반 추상화를 제공합니다. 응용 프로그램 컨텍스트 자체는 ResourceLoader이므로 응용 프로그램에 배포 별 리소스 인스턴스에 대한 액세스 권한을 제공합니다. MessageSource 지원 : 애플리케이션 컨텍스트는 현지화 된 메시지를 얻는 데 사용되는 인터페이스 인 MessageSource를 구현합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.