IOC Container 연동

인프런 Spring WEB MVC 강의를 듣고 정리 한 내용입니다.

SpringIOC 를 Servlet에 연동을 하려고한다.

maven 의 pom.xml 의존성을 추가함

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webmvc</artifactId>
  <version>5.1.3.RELEASE</version>
</dependency>

web.xml 변경

  • 이전 서블릿에서 사용했던 servlet listener (ServletContextListener 구현체) 대신에 Spring에서 지원하는 ContextLoaderListener로 변경 해줌

변경 전

<listener>
  <listener-class>me.morris.MyListener</listener-class>
</listener>

spring에서 지원하는 org.springframework.web.context.ContextLoaderListener

: 스프링 IOC 컨테이너 applicationcontext 를 servlet의 생명주기에 맞춰서 servletcontext에 등록해주고 , 종료할때 applicationcontext를 제거하는 역할을 함

변경 후

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

applicationcontext의 위치, 파일 을 파라미터로 지정해줘야함

contextClass 등록

ContextLoader를 통해 ApplicationContext를 등록 해줘야한다.

web.xml

contextClass : applicationContext를 어떤 방법으로 등록을 할것인가?(Java Configure, Xml Configure ...)

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

<context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>me.morris.AppConfig</param-value>
</context-param>

me.morris.AppConfig.java

package me.morris;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan
public class AppConfig {

}

HelloService.java 서비스 빈으로 등록

package me.morris;

import org.springframework.stereotype.Service;

@Service
public class HelloService {
    public String getName(){
        return "morrisKim";
    }
}

web.xml에 아래와 같이 오류가 난다고 한다면??아래의 순서대로 태그를 나열하면 해결된다.

The content of element type "web-app" must match "(icon?,display-name?,description?,distributable?,context-param*,filter*,filter-mapping*,listener*,servlet*,servlet-mapping*,session-config?,mime-mapping*,welcome-file-list?,error-page*,taglib*,resource-env-ref*,resource-ref*,security-constraint*,login-config?,security-role*,env-entry*,ejb-ref*,ejb-local-ref*)".

Web ApplicationContext 불러오기

아래를 보면 ContextLoaderListener.class가 initwebApplicationContext를 통하여 context를 지정해준다.

99 servletContext.setAttribute(applicationContextName, context);

servletContext에 등록이 되는 것을 알 수 있다.

그 이후에는 이전에 만들었던 HelloServlet.java 클래스로 이동해서 doGet메서드에 서 ApplicationContext를 불러 와보자.

servletContext에 WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE 라는 이름으로 ApplicationContext가 등록이 되어있으므로, 아래와 같이 불러와서 BeanFactory에서 HelloService.class 를 불러와서 사용이 가능하다.

HelloServlet.java

...
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

  ApplicationContext context = (ApplicationContext) getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
  HelloService helloService = context.getBean(HelloService.class);

  System.out.println("doGet");
  resp.getWriter().println("" +
                           "<html>\n" +
                           "<body>\n" +
                           "<h2>Hello Servlet!" +helloService.getName()+"</h2>\n" +
                           "</body>\n" +
                           "</html>\n");
}
...

이로써 IOC 컨테이너를 Servlet에서 사용 할 수 있는 방법을 알 아 볼 수 있었다.

url 하나당 서블릿 하나씩 만들어 나간다면, 설정이 계속 추가가 되며, 여러 서블릿에서 공통적으로 쓰는 것들을 어떻게 해결을 할수 있을까?

그래서 나온것이 FrontController

FrontController의 역할을 하는 하나의 Servlet을 설정해주고 url을 구분하는 방법을 나타냄

SpringWebMVC에서는FrontController로 DispatcherServlet 이라는 것구현해놓았다.

+ Recent posts