pom.xml 추가
(스프링 부트는 버전을 명시하지 않아도 되지만 현재는 그렇지 않기에 버전 명시하는 것이 필수이다.)
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.3.RELEASE</version>
</dependency>
리스너 변경 (스프링이 지원해주는 리스너로 변경)
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
- ContextLoaderListener : ApplicationContext(Spring IOC Container)를 서블릿 Application의 Lifecycle에 맞추어서 바인딩해주는 역할
- ApplicationContext를 ServletContext에 등록
- Servlet 종료 시점에 ApplicationContext 제거
https://jwdeveloper.tistory.com/74?category=823920
(SPRING) IoC 컨테이너 - ApplicationContext와다양한 빈 설정 방법
org.springframework.bootspring-boot-starter-web spring-boot-starter-web를 추가할 경우 대부분의 기본적인 의존성들이 들어온다...
jwdeveloper.tistory.com
설정 파일 생성 (@Configuration , @ComponentScan)
@Configuration
@ComponentScan
public class AppConfig {
}
HelloService.class Bean 등록
@Service
public class HelloService {
public String getName() {
return "junwoo";
}
}
Listener의 contextClass 설정(ACWA) - Bean을 생성
<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.choi.AppConfig</param-value>
</context-param>
Class ContextLoader
application-context을 위한 초기화 작업을 진행한다. (이는 ContextLoaderListener에 의해 호출된다.)
Create a new ContextLoader that will create a web application context based on the "contextClass" and "contextConfigLocation" servlet context-params. See class-level documentation for details on default values for each.
This constructor is typically used when declaring the ContextLoaderListener subclass as a <listener> within web.xml, as a no-arg constructor is required.
The created application context will be registered into the ServletContext under the attribute name WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE and subclasses are free to call the closeWebApplicationContext(javax.servlet.ServletContext) method on container shutdown to close the application context.
"contextClass"및 "contextConfigLocation"서블릿 콘텍스트 매개 변수를 기반으로 웹 애플리케이션 콘텍스트를 작성하는 새 "ContextLoader"를 작성하십시오.
이 생성자는 일반적으로 인수가 없는 생성자가 필요하므로 ContextLoaderListener 서브 클래스를 web.xml 내부에서 선언할 때 사용됩니다.
작성된 애플리케이션 콘텍스트는 속성 이름
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE로 ServletContext에 등록되며 서브 클래스는 컨테이너 종료 시 closeWebApplicationContext (javax.servlet.ServletContext) 메서드를 호출하여 애플리케이션 콘텍스트를 닫을 수 있습니다.
하 해석이 힘드네 영어공부 좀 해야겠다...
Servlet에서 Bean 불러오기
ApplicationContext context = (ApplicationContext) getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
HelloService bean = context.getBean(HelloService.class);
아까 분명히 나는 Listener를 org.springframework.web.context.ContextLoaderListener로 변경하였기에
이제는 MyListener는 동작하지 않는다.
위에서 불러온 Bean에 해당하는 getName()을 호출하면
HelloService의 return 값 "junwoo"가 전시될 것이다.
resp.getWriter().println("<html>");
resp.getWriter().println("<head>");
resp.getWriter().println("<body>");
resp.getWriter().println("<h1>Hello," + bean.getName() + "</h1>");
resp.getWriter().println("</body>");
resp.getWriter().println("</head>");
resp.getWriter().println("</html>");
이제까지 했던 방법은 Spring IOC Container를 이용하는 방법이었다.
여기서 문제는 url 하나당 servlet 하나라는 문제가 발생한다.
<filter>
<filter-name> myfilter </filter-name>
<filter-class> me.choi.MyFilter </filter-class>
</filter>
<filter-mapping>
<filter-name> myfilter </filter-name>
<servlet-name> hello </servlet-name>
</filter-mapping>
공통적으로 처리해야 하는 servlet은 어떻게 처리할까?
http://www.corej2eepatterns.com/FrontController.htm
Core J2EE Patterns
www.corej2eepatterns.com
하나의 컨트롤러만을 사용하여
해당 컨트롤러가 요청을 받아
각각의 핸들러들에게 분배(dispatch)해주는 디자인 패턴
근데 이미 Spring은 위의 FrontController를 구현해놓았다.
이것이 바로 DispatcherServlet이다.
그림에서 Root WebApplicationContext는
우리가 등록한 서블릿에 해당한다.
<filter>
<filter-name>myfilter</filter-name>
<filter-class>me.choi.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myfilter</filter-name>
<servlet-name>hello</servlet-name>
</filter-mapping>
DispatcherServlet은 해당 Root WebApplicationContext를 상속받는
Application Context를 하나 더 만든다.
굳이 이러한 상속관계를 만드는 이유는 무엇일까?
상속관계로 만든다면 부모에 해당하는 Root WebApplicationContext는 다른 자원(servlet)들이 공유할 수 있게 된다.
반면에 DispatcherServlet이 만든 Root WebApplicationContext를 상속받는 Application Context는 자기만 사용할 수 있도록 즉
DispatcherServlet Scope 안에서만 사용이 가능하다.
여기서 주의해서 볼 점은 Root WebApplicationContext에는 web과 관련된 자원들은 존재하지 않는다.
왜냐면 Service와 Repository는 다른 Servlet들이 공유할 수 있는 자원이기 때문이다.
코드 참조
https://github.com/mike6321/Spring/tree/master/SpringMVC/java-servlet-demo
mike6321/Spring
Contribute to mike6321/Spring development by creating an account on GitHub.
github.com
'Spring > Spring MVC' 카테고리의 다른 글
(SERVLET) DispatcherServlet의 내부 살펴보기 (0) | 2020.01.17 |
---|---|
(SERVLET) 스프링 MVC 연동 (0) | 2020.01.12 |
(SERVLET) 서블릿 리스너와 서블릿 필터 (0) | 2020.01.11 |
(SERVLET) 서블릿 애플리케이션 개발 (0) | 2020.01.11 |
(SERVLET) Servlet 개요 (0) | 2020.01.11 |