1. 소개

웹 애플리케이션에서 Spring을 사용할 때 모든 것을 연결하는 애플리케이션 컨텍스트를 구성하는 몇 가지 옵션이 있습니다.

이 기사에서는 Spring이 제공하는 가장 일반적인 옵션을 분석하고 설명 할 것입니다.

2. 루트 웹 애플리케이션 컨텍스트

모든 Spring 웹앱에는 라이프 사이클에 연결된 관련 애플리케이션 컨텍스트 인 루트 웹 애플리케이션 컨텍스트가 있습니다.

이것은 Spring Web MVC 이전의 오래된 기능이므로 특별히 웹 프레임 워크 기술과 관련이 없습니다.

컨텍스트는 애플리케이션이 시작될 때 시작되고 서블릿 컨텍스트 리스너 덕분에 중지되면 삭제됩니다. 모든 ApplicationContext 구현에이 기능이있는 것은 아니지만 가장 일반적인 컨텍스트 유형도 런타임에 새로 고칠 수 있습니다 .

웹 애플리케이션의 컨텍스트는 항상 WebApplicationContext 의 인스턴스입니다 . 이는 ServletContext 액세스를위한 계약 으로 ApplicationContext확장하는 인터페이스 입니다.

어쨌든 응용 프로그램은 일반적으로 이러한 구현 세부 사항에 대해 관심을 가져서는 안됩니다. 루트 웹 응용 프로그램 컨텍스트는 단순히 공유 빈을 정의하는 중앙 집중식 장소입니다.

2.1. 의 ContextLoaderListener

이전 섹션에서 설명한 루트 웹 애플리케이션 컨텍스트 spring-web 모듈의 일부인 org.springframework.web.context.ContextLoaderListener 클래스의 리스너에 의해 관리됩니다 .

기본적으로 리스너는 /WEB-INF/applicationContext.xml 에서 XML 애플리케이션 컨텍스트를로드합니다 . 그러나 이러한 기본값은 변경할 수 있습니다. 예를 들어 XML 대신 Java 어노테이션을 사용할 수 있습니다.

webapp 디스크립터 ( web.xml 파일)에서 또는 Servlet 3.x 환경에서 프로그래밍 방식 으로이 리스너를 구성 할 수 있습니다.

다음 섹션에서는 이러한 각 옵션에 대해 자세히 살펴 보겠습니다.

2.2. 사용 의 web.xml 과 XML 응용 프로그램 컨텍스트

web.xml을 사용할 때 평소와 같이 리스너를 구성합니다.

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

contextConfigLocation 매개 변수를 사용하여 XML 컨텍스트 구성의 대체 위치를 지정할 수 있습니다 .

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/rootApplicationContext.xml</param-value>
</context-param>

또는 쉼표로 구분 된 둘 이상의 위치 :

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/context1.xml, /WEB-INF/context2.xml</param-value>
</context-param>

패턴을 사용할 수도 있습니다.

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

어떤 경우 든 지정된 위치에서로드 된 모든 Bean 정의를 결합하여 하나의 컨텍스트 만 정의됩니다.

2.3. 사용 의 web.xml 과 자바 응용 프로그램 컨텍스트

기본 XML 기반 컨텍스트 외에 다른 유형의 컨텍스트를 지정할 수도 있습니다. 예를 들어 Java 어노테이션 구성을 대신 사용하는 방법을 살펴 보겠습니다.

contextClass 매개 변수를 사용하여 인스턴스화 할 컨텍스트 유형을 리스너에게 알려줍니다.

<context-param>
    <param-name>contextClass</param-name>
    <param-value>
        org.springframework.web.context.support.AnnotationConfigWebApplicationContext
    </param-value>
</context-param>

모든 유형의 컨텍스트에는 기본 구성 위치가있을 수 있습니다. 우리의 경우 AnnotationConfigWebApplicationContext 에는 하나가 없으므로 제공해야합니다.

따라서 하나 이상의 어노테이션이 달린 클래스를 나열 할 수 있습니다.

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        com.baeldung.contexts.config.RootApplicationConfig,
        com.baeldung.contexts.config.NormalWebAppConfig
    </param-value>
</context-param>

또는 컨텍스트에 하나 이상의 패키지를 스캔하도록 지정할 수 있습니다.

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>com.baeldung.bean.config</param-value>
</context-param>

물론 두 가지 옵션을 혼합하고 일치시킬 수 있습니다.

2.4. Servlet 3.x를 사용한 프로그래밍 방식 구성

Servlet API 버전 3은 web.xml 파일을 통한 구성을 완전히 선택적으로 만들었습니다 . 라이브러리는 리스너, 필터, 서블릿 등을 등록 할 수있는 XML 구성의 일부인 웹 조각을 제공 할 수 있습니다.

또한 사용자는 서블릿 기반 애플리케이션의 모든 요소를 ​​프로그래밍 방식으로 정의 할 수있는 API에 액세스 할 수 있습니다.

스프링 웹 모듈 차종은 이러한 기능을 사용하여 시작할 때 응용 프로그램의 구성 요소를 등록하기 위해 API를 제공합니다.

Spring은 org.springframework.web.WebApplicationInitializer 클래스의 인스턴스에 대한 애플리케이션의 클래스 경로를 스캔합니다 . 이것은 단일 메소드가있는 인터페이스입니다. void onStartup (ServletContext servletContext)는 애플리케이션 시작시 호출되는 ServletException 을 발생시킵니다.

이제이 기능을 사용하여 이전에 본 것과 동일한 유형의 루트 웹 애플리케이션 컨텍스트를 만드는 방법을 살펴 보겠습니다.

2.5. Servlet 3.x 및 XML 응용 프로그램 컨텍스트 사용

2.2 절에서와 같이 XML 컨텍스트로 시작해 보겠습니다.

앞서 언급 한 onStartup 메서드를 구현합니다 .

public class ApplicationInitializer implements WebApplicationInitializer {
    
    @Override
    public void onStartup(ServletContext servletContext) 
      throws ServletException {
        //...
    }
}

구현을 한 줄씩 세분화합시다.

먼저 루트 컨텍스트를 만듭니다. XML을 사용하려면 XML 기반 애플리케이션 컨텍스트 여야하고 웹 환경에 있기 때문에 WebApplicationContext구현 해야합니다.

따라서 첫 번째 줄은 앞서 살펴본 contextClass 매개 변수 의 명시 적 버전이며 사용할 특정 컨텍스트 구현을 결정합니다.

XmlWebApplicationContext rootContext = new XmlWebApplicationContext();

그런 다음 두 번째 줄에서 빈 정의를로드 할 컨텍스트를 알려줍니다. 다시 말하지만 setConfigLocationsweb.xmlcontextConfigLocation 매개 변수와 유사한 프로그래밍 방식입니다 .

rootContext.setConfigLocations("/WEB-INF/rootApplicationContext.xml");

마지막으로 루트 컨텍스트 ContextLoaderListener만들고 서블릿 컨테이너에 등록합니다. 보시다시피 ContextLoaderListener 에는 WebApplicationContext 를 받아 애플리케이션에서 사용할 수 있도록 하는 적절한 생성자가 있습니다.

servletContext.addListener(new ContextLoaderListener(rootContext));

2.6. Servlet 3.x 및 Java 애플리케이션 컨텍스트 사용

어노테이션 기반 컨텍스트를 사용하려면 이전 섹션의 코드 조각을 변경하여 대신 AnnotationConfigWebApplicationContext인스턴스화 할 수 있습니다  .

그러나 동일한 결과를 얻기 위해보다 전문화 된 접근 방식을 살펴 보겠습니다.

WebApplicationInitializer의 앞에서 보았으므로 클래스는 범용 인터페이스입니다. Spring은 AbstractContextLoaderInitializer 라는 추상 클래스를 포함하여 몇 가지 더 구체적인 구현을 제공합니다 .

이름에서 알 수 있듯이이 작업은 ContextLoaderListener 를 만들고 서블릿 컨테이너에 등록하는 것입니다.

루트 컨텍스트를 빌드하는 방법 만 알려 주면됩니다.

public class AnnotationsBasedApplicationInitializer 
  extends AbstractContextLoaderInitializer {
 
    @Override
    protected WebApplicationContext createRootApplicationContext() {
        AnnotationConfigWebApplicationContext rootContext
          = new AnnotationConfigWebApplicationContext();
        rootContext.register(RootApplicationConfig.class);
        return rootContext;
    }
}

여기서 우리는 더 이상 ContextLoaderListener 를 등록 할 필요가 없다는 것을 알 수 있습니다. 이렇게  하면 약간의 상용구 코드에서 벗어날 수 있습니다.

좀 더 일반적인 setConfigLocations 대신 AnnotationConfigWebApplicationContext에 특정한 register 메소드를 사용하는 것에 유의하십시오 .이를 호출함으로써 개별 @Configuration 어노테이션이 달린 클래스를 컨텍스트에 등록 할 수 있으므로 패키지 스캔을 피할 수 있습니다.

3. 디스패처 서블릿 컨텍스트

이제 다른 유형의 애플리케이션 컨텍스트에 초점을 맞 춥니 다. 이번에는 Spring의 일반적인 웹 애플리케이션 지원의 일부가 아니라 Spring MVC에 특정한 기능을 언급 할 것입니다.

Spring MVC 애플리케이션에는 최소한 하나의 Dispatcher Servlet이 구성되어 있습니다 (하지만 둘 이상일 수 있습니다.이 경우에 대해서는 나중에 설명하겠습니다). 이것은 들어오는 요청을 수신하고 적절한 컨트롤러 메소드로 디스패치하고 뷰를 반환하는 서블릿입니다.

DispatcherServlet 에는 연관된 애플리케이션 컨텍스트가 있습니다. 이러한 컨텍스트에 정의 된 Bean은 서블릿을 구성하고 컨트롤러 및 뷰 리졸버와 같은 MVC 개체를 정의합니다.

먼저 서블릿의 컨텍스트를 구성하는 방법을 살펴 보겠습니다. 나중에 좀 더 자세한 내용을 살펴 보겠습니다.

3.1. 사용 의 web.xml 과 XML 응용 프로그램 컨텍스트

DispatcherServlet 은 일반적으로 이름과 매핑을 사용하여 web.xml 에서 선언됩니다 .

<servlet>
    <servlet-name>normal-webapp</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>normal-webapp</servlet-name>
    <url-pattern>/api/*</url-pattern>
</servlet-mapping>

달리 지정하지 않으면로드 할 XML 파일을 결정하는 데 서블릿의 이름이 사용됩니다. 이 예에서는 WEB-INF / normal-webapp-servlet.xml 파일을 사용합니다  .

ContextLoaderListener 와 비슷한 방식으로 XML 파일에 대한 하나 이상의 경로를 지정할 수도 있습니다 .

<servlet>
    ...
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/normal/*.xml</param-value>
    </init-param>
</servlet>

3.2. 사용 의 web.xml 과 자바 응용 프로그램 컨텍스트

다른 유형의 컨텍스트를 사용하려면 다시 ContextLoaderListener 를 사용합니다. 즉, 적절한 contextConfigLocation 과 함께 contextClass 매개 변수를 지정합니다 .

<servlet>
    <servlet-name>normal-webapp-annotations</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
        </param-value>
    </init-param>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>com.baeldung.contexts.config.NormalWebAppConfig</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

3.3. Servlet 3.x 및 XML 응용 프로그램 컨텍스트 사용

다시 한 번, DispatcherServlet 을 프로그래밍 방식으로 선언하는 두 가지 다른 메서드를 살펴보고 하나는 XML 컨텍스트에 적용하고 다른 하나는 Java 컨텍스트에 적용합니다.

이제 일반 WebApplicationInitializer 와 XML 애플리케이션 컨텍스트 부터 시작하겠습니다 .

이전에 보았 듯이 onStartup 메서드 를 구현해야합니다 . 그러나 이번에는 디스패처 서블릿도 만들고 등록합니다.

XmlWebApplicationContext normalWebAppContext = new XmlWebApplicationContext();
normalWebAppContext.setConfigLocation("/WEB-INF/normal-webapp-servlet.xml");
ServletRegistration.Dynamic normal
  = servletContext.addServlet("normal-webapp", 
    new DispatcherServlet(normalWebAppContext));
normal.setLoadOnStartup(1);
normal.addMapping("/api/*");

위의 코드와 동등한 web.xml 구성 요소 사이에 쉽게 병렬을 그릴 수 있습니다 .

3.4. Servlet 3.x 및 Java 애플리케이션 컨텍스트 사용

이번에는 WebApplicationInitializer : AbstractDispatcherServletInitializer 의 특수 구현을 사용하여 어노테이션 기반 컨텍스트를 구성합니다 .

이는 이전에 본 것처럼 루트 웹 애플리케이션 컨텍스트를 만드는 것 외에도 최소한의 상용구로 하나의 디스패처 서블릿을 등록 할 수있는 추상 클래스입니다.

@Override
protected WebApplicationContext createServletApplicationContext() {
 
    AnnotationConfigWebApplicationContext secureWebAppContext
      = new AnnotationConfigWebApplicationContext();
    secureWebAppContext.register(SecureWebAppConfig.class);
    return secureWebAppContext;
}

@Override
protected String[] getServletMappings() {
    return new String[] { "/s/api/*" };
}

여기서 우리는 루트 컨텍스트에 대해 이전에 보았던 것과 똑같이 서블릿과 관련된 컨텍스트를 생성하는 방법을 볼 수 있습니다. 또한 web.xml 에서와 같이 서블릿의 매핑을 지정하는 방법이 있습니다.

4. 부모 및 자식 컨텍스트

지금까지 루트 웹 애플리케이션 컨텍스트와 디스패처 서블릿 컨텍스트의 두 가지 주요 컨텍스트 유형을 살펴 보았습니다. 그런 다음 질문이있을 수 있습니다. 이러한 컨텍스트가 관련되어 있습니까?

네, 그렇습니다. 사실 루트 컨텍스트는 모든 디스패처 서블릿 컨텍스트의 상위입니다. 따라서 루트 웹 애플리케이션 컨텍스트에 정의 된 Bean은 각 디스패처 서블릿 컨텍스트에 표시되지만 그 반대의 경우는 아닙니다.

따라서 일반적으로 루트 컨텍스트는 서비스 빈을 정의하는 데 사용되는 반면 디스패처 컨텍스트에는 MVC와 특별히 관련된 빈이 포함됩니다.

또한 디스패처 서블릿 컨텍스트를 프로그래밍 방식으로 생성하는 방법도 살펴 보았습니다. 부모를 수동으로 설정하면 Spring은 우리의 결정을 무시하지 않으며이 섹션은 더 이상 적용되지 않습니다.

더 간단한 MVC 애플리케이션에서는 하나의 디스패처 서블릿에 단일 컨텍스트를 연결하는 것으로 충분합니다. 지나치게 복잡한 솔루션이 필요하지 않습니다!

그래도 상위-하위 관계는 여러 디스패처 서블릿이 구성된 경우 유용합니다. 그러나 우리는 언제 둘 이상을 가지고 귀찮게해야합니까?

일반적으로 여러 세트의 MVC 구성이 필요할 때 여러 디스패처 서블릿을 선언 합니다. 예를 들어, 기존 MVC 애플리케이션과 함께 REST API가 있거나 웹 사이트의 Security되지 않은 Security 섹션이있을 수 있습니다.

참고 : AbstractDispatcherServletInitializer (3.4 절 참조)를 확장 할 때 루트 웹 애플리케이션 컨텍스트와 단일 디스패처 서블릿을 모두 등록합니다.

따라서 하나 이상의 서블릿을 원하면 여러 AbstractDispatcherServletInitializer 구현이 필요 합니다. 그러나 루트 컨텍스트를 하나만 정의 할 수 있습니다. 그렇지 않으면 응용 프로그램이 시작되지 않습니다.

다행히 createRootApplicationContext 메서드는 null 을 반환 할 수 있습니다 . 따라서 하나의 AbstractContextLoaderInitializer루트 컨텍스트를 생성하지 않는 여러 AbstractDispatcherServletInitializer 구현을 가질 수 있습니다 . 이러한 시나리오에서는 @Order를 사용 하여 이니셜 라이저를 명시 적으로 주문하는 것이 좋습니다 .

또한 AbstractDispatcherServletInitializer 는 주어진 이름 ( dispatcher )으로 서블릿을 등록하며 물론 동일한 이름을 가진 여러 서블릿을 가질 수 없습니다. 따라서 getServletName 을 재정의해야합니다 .

@Override
protected String getServletName() {
    return "another-dispatcher";
}

5.  부모 및 자식 컨텍스트  예제 

예를 들어 세계에서 액세스 할 수있는 공개 영역과 MVC 구성이 서로 다른 Security 영역과 같은 두 가지 응용 프로그램 영역이 있다고 가정합니다. 여기에서는 다른 메시지를 출력하는 두 개의 컨트롤러를 정의합니다.

또한 일부 컨트롤러에 상당한 리소스를 보유하는 서비스가 필요하다고 가정합니다. 유비쿼터스 사례는 지속성입니다. 그런 다음 해당 서비스를 한 번만 인스턴스화하여 리소스 사용량을 두 배로 늘리는 것을 방지하고 Do n't Repeat Yourself 원칙을 믿기 때문입니다!

이제 예제를 진행하겠습니다.

5.1. 공유 서비스

hello world 예제에서는 지속성 대신 간단한 인사 서비스를 사용했습니다.

package com.baeldung.contexts.services;

@Service
public class GreeterService {
    @Resource
    private Greeting greeting;
    
    public String greet() {
        return greeting.getMessage();
    }
}

컴포넌트 스캐닝을 사용하여 루트 웹 애플리케이션 컨텍스트에서 서비스를 선언합니다.

@Configuration
@ComponentScan(basePackages = { "com.baeldung.contexts.services" })
public class RootApplicationConfig {
    //...
}

대신 XML을 선호 할 수 있습니다.

<context:component-scan base-package="com.baeldung.contexts.services" />

5.2. 컨트롤러

서비스를 사용하고 인사말을 출력하는 두 개의 간단한 컨트롤러를 정의 해 보겠습니다.

package com.baeldung.contexts.normal;

@Controller
public class HelloWorldController {

    @Autowired
    private GreeterService greeterService;
    
    @RequestMapping(path = "/welcome")
    public ModelAndView helloWorld() {
        String message = "<h3>Normal " + greeterService.greet() + "</h3>";
        return new ModelAndView("welcome", "message", message);
    }
}

//"Secure" Controller
package com.baeldung.contexts.secure;

String message = "<h3>Secure " + greeterService.greet() + "</h3>";

보시다시피 컨트롤러는 두 개의 서로 다른 패키지에 있으며 하나는 "보통"이고 다른 하나는 "Security"이라는 서로 다른 메시지를 인쇄합니다.

5.3. 디스패처 서블릿 컨텍스트

앞서 말했듯이 각 컨트롤러마다 하나씩 두 개의 다른 디스패처 서블릿 컨텍스트가 있습니다. 따라서 Java로 정의 해 보겠습니다.

//Normal context
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.baeldung.contexts.normal" })
public class NormalWebAppConfig implements WebMvcConfigurer {
    //...
}

//"Secure" context
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.baeldung.contexts.secure" })
public class SecureWebAppConfig implements WebMvcConfigurer {
    //...
}

또는 원하는 경우 XML로 :

<!-- normal-webapp-servlet.xml -->
<context:component-scan base-package="com.baeldung.contexts.normal" />

<!-- secure-webapp-servlet.xml -->
<context:component-scan base-package="com.baeldung.contexts.secure" />

5.4. 함께 모아서

이제 모든 조각을 얻었으므로 Spring에 연결하도록 지시하면됩니다. 루트 컨텍스트를로드하고 두 개의 디스패처 서블릿을 정의해야합니다. 이를 수행하는 여러 가지 방법을 보았지만 이제 Java 시나리오와 XML 시나리오의 두 가지 시나리오에 중점을 둘 것입니다. Java부터 시작하겠습니다.

루트 컨텍스트를로드하기 위해 AbstractContextLoaderInitializer정의합니다 .

@Override
protected WebApplicationContext createRootApplicationContext() {
    AnnotationConfigWebApplicationContext rootContext
      = new AnnotationConfigWebApplicationContext();
    rootContext.register(RootApplicationConfig.class);
    return rootContext;
}

그런 다음 두 개의 서블릿을 만들어야하므로 AbstractDispatcherServletInitializer의 두 개의 하위 클래스를 정의 합니다. 첫째, "일반적인"것 :

@Override
protected WebApplicationContext createServletApplicationContext() {
    AnnotationConfigWebApplicationContext normalWebAppContext
      = new AnnotationConfigWebApplicationContext();
    normalWebAppContext.register(NormalWebAppConfig.class);
    return normalWebAppContext;
}

@Override
protected String[] getServletMappings() {
    return new String[] { "/api/*" };
}

@Override
protected String getServletName() {
    return "normal-dispatcher";
}

그런 다음 다른 컨텍스트를로드하고 다른 경로에 매핑되는 "Security"항목 :

@Override
protected WebApplicationContext createServletApplicationContext() {
    AnnotationConfigWebApplicationContext secureWebAppContext
      = new AnnotationConfigWebApplicationContext();
    secureWebAppContext.register(SecureWebAppConfig.class);
    return secureWebAppContext;
}

@Override
protected String[] getServletMappings() {
    return new String[] { "/s/api/*" };
}

@Override
protected String getServletName() {
    return "secure-dispatcher";
}

그리고 우리는 끝났습니다! 우리는 이전 섹션에서 만진 것을 방금 적용했습니다.

지금까지 논의한 부분을 결합하여 web.xml 에서도 동일한 작업을 수행 할 수 있습니다 .

루트 애플리케이션 컨텍스트를 정의하십시오.

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

"일반"디스패처 컨텍스트 :

<servlet>
    <servlet-name>normal-webapp</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>normal-webapp</servlet-name>
    <url-pattern>/api/*</url-pattern>
</servlet-mapping>

마지막으로 "안전한"컨텍스트 :

<servlet>
    <servlet-name>secure-webapp</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>secure-webapp</servlet-name>
    <url-pattern>/s/api/*</url-pattern>
</servlet-mapping>

6. 여러 컨텍스트 결합

부모-자식이 아닌 다른 방법으로 여러 구성 위치를 결합 하고 큰 컨텍스트를 분할하고 다른 문제를 더 잘 분리 할 수 ​​있습니다. 이미 한 가지 예를 보았습니다. 여러 경로 또는 패키지로 contextConfigLocation지정할 때 Spring은 마치 단일 XML 파일이나 Java 클래스로 작성된 것처럼 모든 빈 정의를 순서대로 결합하여 단일 컨텍스트를 빌드합니다.

그러나 우리는 다른 방법으로 비슷한 효과를 얻을 수 있으며 다른 접근 방식을 함께 사용할 수도 있습니다. 옵션을 살펴 보겠습니다.

한 가지 가능성은 다른 기사에서 설명하는 구성 요소 스캐닝 입니다.

6.1. 다른 컨텍스트로 컨텍스트 가져 오기

또는 컨텍스트 정의가 다른 것을 가져 오도록 할 수 있습니다. 시나리오에 따라 수입품 종류가 다릅니다.

Java에서 @Configuration 클래스 가져 오기 :

@Configuration
@Import(SomeOtherConfiguration.class)
public class Config { ... }

Java에서 다른 유형의 리소스 (예 : XML 컨텍스트 정의)로드 :

@Configuration
@ImportResource("classpath:basicConfigForPropertiesTwo.xml")
public class Config { ... }

마지막으로 XML 파일을 다른 파일에 포함 :

<import resource="greeting.xml" />

따라서 우리는 멋진 응용 프로그램을 만들기 위해 협력하는 서비스, 구성 요소, 컨트롤러 등을 구성하는 많은 방법이 있습니다. 그리고 좋은 점은 IDE가 모든 것을 이해한다는 것입니다!

7. 스프링 부트 웹 애플리케이션

Spring Boot는 애플리케이션의 구성 요소를 자동으로 구성 하므로 일반적으로 구성 방법에 대해 생각할 필요가 없습니다.

그럼에도 불구하고 Boot는 지금까지 보았던 기능을 포함하여 Spring 기능을 사용합니다. 몇 가지 주목할만한 차이점을 살펴 보겠습니다.

임베디드 컨테이너에서 실행되는 Spring Boot 웹 애플리케이션 은 설계 상 WebApplicationInitializer실행하지 않습니다 .

필요한 경우 선택한 배포 전략에 따라 SpringBootServletInitializer  또는 ServletContextInitializer 에 동일한 논리를 대신 작성할 수 있습니다  .

그러나이 기사에서 볼 수 있듯이 서블릿, 필터 및 리스너를 추가하는 경우에는 그렇게 할 필요가 없습니다. 사실 Spring Boot는 모든 서블릿 관련 빈을 컨테이너에 자동으로 등록합니다.

@Bean
public Servlet myServlet() { ... }

이렇게 정의 된 개체는 규칙에 따라 매핑됩니다. 필터는 자동으로 / *, 즉 모든 요청에 ​​매핑됩니다. 단일 서블릿을 등록하면 /에 매핑되고, 그렇지 않으면 각 서블릿이 해당 빈 이름에 매핑됩니다.

위의 규칙이 작동하지 않는다면 대신 FilterRegistrationBean , ServletRegistrationBean  또는 ServletListenerRegistrationBean을 정의 할 수 있습니다 . 이러한 클래스를 통해 등록의 세부 사항을 제어 할 수 있습니다.

8. 결론

이 기사에서는 Spring 웹 애플리케이션을 구조화하고 구성하는 데 사용할 수있는 다양한 옵션에 대해 심층적으로 살펴 보았습니다.

우리는 일부 기능, 특히 엔터프라이즈 애플리케이션의 공유 컨텍스트에 대한 지원을 생략했습니다.이 기능 은 작성 당시 아직 Spring 5에서 누락되었습니다 .

이러한 모든 예제 및 코드 스 니펫의 구현은 GitHub 프로젝트 에서 찾을 수 있습니다 .