ServletContext로 DB 커넥션 객체 관리하기
DB를 사용하는 서블릿들이 호출될때마다 DB 커넥션을 생성하지 않고, 웹 어플리케이션이 시작될 때 생성해서 ServletContext에 저장하면 필요한 서블릿에서 커넥션 인스턴스를 꺼내 쓸 수 있다.
1. 공유 자원을 준비하는 서블릿 작성
먼저 웹 어플리케이션이 시작될 때 DB 커넥션 객체를 준비하는 서블릿을 작성한다.
AppInitServlet.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
public class AppInitServlet extends HttpServlet {
// init() : 서블릿 객체가 생성될때 최초로 호출
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("AppInitServlet.init() called");
super.init(config);
// 모든 서블릿이 사용할 수 있도록 ServletContext 인스턴스에 저장
ServletContext sc = this.getServletContext();
try {
Class.forName(sc.getInitParameter("driver"));
Connection conn = DriverManager.getConnection(
sc.getInitParameter("url"),
sc.getInitParameter("username"),
sc.getInitParameter("password")
);
sc.setAttribute("conn", conn);
} catch (Throwable e) {
throw new ServletException(e);
}
}
// destroy() : 서블릿이 언로드될때(서버 종료, 웹 어플리케이션 종료, 서블릿 재로딩) 호출
@Override
public void destroy() {
System.out.println("AppInitServlet.destroy() called");
super.destroy();
Connection conn = (Connection) this.getServletContext().getAttribute("conn");
try {
if(conn != null && !conn.isClosed()) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
|
cs |
공유 자원(DB 커넥션 객체)을 준비하는 작업을 하기 위해 service()를 override한다.
그리고 이 서블릿이 언로드될 때 DB 커넥션 객체를 해제시키기 위해(DB 연결 종료) destory()를 override한다.
기존의 초기화, 마무리 작업을 그대로 쓰기 위해 슈퍼 클래스의 메소드 호출부 다음에 각각 필요한 코드를 작성해준다.
2. 서블릿 배치와 <load-on-startup> 태그
web.xml에 위에서 작성한 AppInitServlet의 배치 정보를 작성한다.
web.xml
1
2
3
4
5
6
|
<!-- 서블릿 선언 -->
<servlet>
<servlet-name>AppInitServlet</servlet-name>
<servlet-class>com.atoz_develop.spms.servlets.AppInitServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
|
cs |
클라이언트 요청이 없어도 서블릿이 생성돼야 하므로 <load-on-startup> 태그를 추가한다.
해당 태그를 지정하면 웹 어플리케이션이 시작될때 자동으로 생성된다.
1이라고 입력한 값은 생성 순서를 의미한다.
생성 순서가 같으면 먼저 선언된 서블릿이 먼저 생성된다.
클라이언트 요청을 처리하는 서블릿이 아니므로 URL 매핑 정보는 지정하지 않는다.
3. ServletContext에 저장된 DB 커넥션 사용
서블릿에서 직접 DB 커넥션 객체를 얻는 코드를 ServletContext에서 꺼내쓰도록 변경한다.
1
2
3
4
5
6
7
8
9
10
11
|
/*
// DB 커넥션 객체를 얻는 기존 코드 주석 처리
Class.forName(sc.getInitParameter("driver"));
conn = DriverManager.getConnection(
sc.getInitParameter("url"),
sc.getInitParameter("username"),
sc.getInitParameter("password")
);*/
// ServletContext에 저장된 DB 커넥션 객체 사용
conn = (Connection) sc.getAttribute("conn");
stmt = conn.createStatement();
|
cs |
추가로 DB 커넥션 객체를 서블릿에서 관리하지 않으므로 finally 블록에 conn.close();와 같은 코드도 삭제한다.
코드 변경 후 배치하여 테스트해보면 동일하게 정상 동작함을 확인할 수 있다.
추가로 공유 객체를 관리하는데에는 이렇게 서블릿을 따로 구현해서 하는 방법보다 서블릿 컨테이너의 이벤트 리스너를 구현하는 것이 더 좋은 방법이다.
'Java·Servlet·JSP' 카테고리의 다른 글
[IntelliJ] 회원가입 예제(MVC) - (5) 로그인/로그아웃(HttpSession) (0) | 2020.02.13 |
---|---|
JSP 액션 태그와 jsp:useBean 사용 예제 (0) | 2020.02.13 |
RequestDispatcher.forward()를 이용한 에러 페이지 출력하기 (0) | 2020.02.12 |
[IntelliJ] 회원가입 예제(MVC) - (4) 뷰(JSP) 분리하기 (0) | 2020.02.12 |
JSP 기본 문법 총 정리 - 템플릿 데이터, JSP 전용 태그, 내장 객체 (2) | 2020.02.11 |
댓글