본문 바로가기
👨‍💻 2. 웹개발_Back end/2-4 JSP & Servlet

[JSP & Servlet] 5장 MVC 아키텍처 (6) - ServletContextListener를 이용한 객체 공유

by 달님🌙 2021. 10. 15.
반응형

 

5.11 ServletContextListener와 객체 공유


1. ServletContextListener를 이용한 공유 객체 준비

- AppInitServlet을 대신해서 MemberDAO를 객체로 만들어서 사용함

 

2. ServletContextListener란?

 

- 서블릿 컨테이너 역할 : 웹 애플리케이션 상태를 모니터링할 수 있도록 알림 기능을 제공

- 서블릿 내에서 사건이나 이벤트가 발생하게 되면 이 ServletContextListener를 통해서 사건이 발생한 것을 알려줌

- 이벤트 리스너 클래스를 하나 만들어서 web.xml에 등록해주면 이벤트가 발생할 때마다 관련 메소드를 호출할 수 있음

 - ServletContextListener 인터페이스를 상속받은 ContextLoaderListener를 구현해서 MemberDAO를 만듬

- 그렇게 되면 contextInitialized() 메서드와 contextDestroyed() 메서드를 오버라이드해서 구현할 수 있음

- contextInitialized()는 웹 애플리케이션이 시작될 때, contextDestroyed()는 웹 애플리케이션이 종료될때 호출됨

 

- ContextLoaderListener라는 인터페이스를 상속받은 ServletContextListener(인터페이스)를 만들어서 사용함

 

- 서블릿들이 공유하는 클래스를 AppInitServlet으로 지정해놓음

- ServletContextListener에서 MemberDAO를 만들도록 준비

 

3. 컨텍스트 리스너 실습 ( _21_MVC_ContextListener )

 

- ServletContextListener 인터페이스를 상속받은 ContextLoaderListener를 구현

- 웹 어플리케이션이 실행되면 MemberDAO를 하나 만든다.

- 만들어진 MemberDAO를 서블릿끼리 공유해서 사용하도록 웹 어플리케이션을변경해보는 예제

 

1) ContextLoaderListener.java 파일 생성

package spms.listener;

import java.sql.Connection;
import java.sql.DriverManager;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import spms.dao.MemberDAO;

public class ContextLoaderListener implements ServletContextListener {
	Connection conn;
	
	@Override
	public void contextInitialized(ServletContextEvent sce) {
		//웹 애플리케이션이 실행되면 자동으로 DB커넥션 생성 및 MemberDAO객체 생성
		try {
			System.out.println("contextInitialized");
			ServletContext sc = sce.getServletContext();
			Class.forName(sc.getInitParameter("driver"));
			conn = DriverManager.getConnection(sc.getInitParameter("url"),
								  	   sc.getInitParameter("username"),
									   sc.getInitParameter("password"));
			MemberDAO memberDAO = new MemberDAO();
			memberDAO.setConnection(conn);
			
			//생성된 MemberDAO객체를 ServletContext 데이터 보관소를 통해 서블릿끼리 공유
			//MemberDAO를 만들어서 ServletContext 데이터 보관소를 통해서 저장하고 
			//저장된  MemberDAO를 사용해서 더이상 서블릿에서 MemberDAO를 생성하는 일이 없도록 만듬
			sc.setAttribute("memberDAO", memberDAO);
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	@Override // 커넥션 끊어주기
	public void contextDestroyed(ServletContextEvent sce) {
		try {
			//웹 애플리케이션이 종료될 때 DB커넥션이 살아있으면 끊어줌
			if(conn != null) {
				conn.close();
			}
			System.out.println("contextDestroyed");
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
}

- MemberDAO를 만들어서 ServletContext 데이터 보관소에 저장하기

 

2) web.xml : 리스너 등록하기

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>_06_JDBCServlet</display-name>
  
  <!-- 컨텍스트 초기화 매개변수 -->
  <context-param>
  	<param-name>driver</param-name>
  	<param-value>com.mysql.jdbc.Driver</param-value>
  </context-param>
  <context-param>
  	<param-name>url</param-name>
  	<param-value>jdbc:mysql://localhost/studydb?serverTimezone=UTC</param-value>
  </context-param>
  <context-param>
  	<param-name>username</param-name>
  	<param-value>study</param-value>
  </context-param>
  <context-param>
  	<param-name>password</param-name>
  	<param-value>study</param-value>
  </context-param>
  
  <!-- 리스너가 등록--> 
  <!-- 웹애플리케이션 실행 -> contextInitialized() 호출 -->
  <!-- 웹애플리케이션 종료 -> contextDesroyed() 호출 -->
  <listener> 
  	<listener-class>spms.listener.ContextLoaderListener</listener-class>
  </listener>

  
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

 

3) MemberListServlet.java 코드 수정

Before

try {
    Connection conn = (Connection)sc.getAttribute("conn");

    MemberDAO memberDAO = new MemberDAO();
    //DAO객체 connection 주입
    memberDAO.setConnection(conn);

After (코드 간소화)

try {			
    //ServletContext 데이터 보관소에 저장되어 있는 MemberDAO객체 꺼내옴
    //DB 커넥션 주입까지 완료된 상태의 MemberDAO
    MemberDAO memberDAO = (MemberDAO)sc.getAttribute("memberDAO");

* 커넥션 부분이 사라지고 MemberDAO 객체 선언 코드가 간단해짐

 

 

4) MemberAddServlet.java 코드 수정

Before

try {
    Connection conn = (Connection)sc.getAttribute("conn");
    MemberDAO memberDAO = new MemberDAO();
    memberDAO.setConnection(conn);

After (코드 간소화)

try {
    Connection conn = (Connection)sc.getAttribute("conn");
    MemberDAO memberDAO = (MemberDAO)sc.getAttribute("memberDAO");

 

5) MemberDeleteServlet.java 코드 수정

Before

try {
    ServletContext sc = this.getServletContext();
    Connection conn = (Connection)sc.getAttribute("conn");	
    MemberDAO memberDAO = new MemberDAO();
    memberDAO.setConnection(conn);

After (코드 간소화)

try {
    ServletContext sc = this.getServletContext();
    MemberDAO memberDAO = (MemberDAO)sc.getAttribute("memberDAO");

 

6) MemberUpdateServlet.java 코드 수정

Before

try {
    Connection conn = (Connection)sc.getAttribute("conn");
    MemberDAO memberDAO = new MemberDAO();
    memberDAO.setConnection(conn);

After (코드 간소화)

//doget과 dopost 모두 변경
try {
    MemberDAO memberDAO = (MemberDAO)sc.getAttribute("memberDAO");

 

7) LoginServlet.java 코드 수정

Before

try {
    ServletContext sc = this.getServletContext();
    Connection conn = (Connection)sc.getAttribute("conn");
    MemberDAO memberDAO = new MemberDAO();
    memberDAO.setConnection(conn);

After (코드 간소화)

try {
    ServletContext sc = this.getServletContext();
    MemberDAO memberDAO = (MemberDAO)sc.getAttribute("memberDAO");

 

8) 실행 화면 (5장 MVC 아키텍처 (5) - DAO객체 만들기 실행 화면 참조)

로그인, 추가, 삭제, 수정 다 잘 실행됨 

 

 

반응형

댓글