Skip to content

Commit 4a0f7f8

Browse files
committed
part07의 게시판 프로젝트들에도 적용 (#41)
web.xml 기반의 ex06-board에도 적용해서 동작을 확인했다.
1 parent 2b9f5a0 commit 4a0f7f8

4 files changed

Lines changed: 124 additions & 0 deletions

File tree

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package org.fp024.servlet.listener;
2+
3+
import javax.servlet.ServletContext;
4+
import javax.servlet.ServletContextEvent;
5+
import javax.servlet.ServletContextListener;
6+
import java.sql.DriverManager;
7+
import java.sql.SQLException;
8+
import java.util.Collections;
9+
import lombok.extern.slf4j.Slf4j;
10+
11+
@Slf4j
12+
public class JDBCDriverCleaner implements ServletContextListener {
13+
protected void deregisterJdbcDrivers(ServletContext servletContext) {
14+
Collections.list(DriverManager.getDrivers())
15+
.forEach(
16+
driver -> {
17+
ClassLoader driverClassLoader = driver.getClass().getClassLoader();
18+
ClassLoader contextClassLoader = servletContext.getClassLoader();
19+
ClassLoader parentClassLoader =
20+
contextClassLoader != null ? contextClassLoader.getParent() : null;
21+
22+
LOGGER.debug(
23+
"### {} 드라이버의 클래스 로더: {}",
24+
driver.getClass().getCanonicalName(),
25+
driverClassLoader != null
26+
? driverClassLoader.getClass().getCanonicalName()
27+
: "Bootstrap ClassLoader");
28+
LOGGER.debug(
29+
"### 현재 서블릿 컨텍스트의 클래스 로더: {}",
30+
contextClassLoader != null
31+
? contextClassLoader.getClass().getCanonicalName()
32+
: "Bootstrap ClassLoader");
33+
LOGGER.debug(
34+
"### 현재 서블릿 컨텍스트의 부모 클래스 로더: {}",
35+
parentClassLoader != null
36+
? parentClassLoader.getClass().getCanonicalName()
37+
: "Bootstrap ClassLoader");
38+
39+
if (driverClassLoader == contextClassLoader
40+
|| driverClassLoader == parentClassLoader) {
41+
try {
42+
DriverManager.deregisterDriver(driver);
43+
LOGGER.info("### {} 드라이버 등록 해제", driver.getClass().getCanonicalName());
44+
} catch (SQLException ex) {
45+
LOGGER.warn("### {} 드라이버 등록 해제 실패", driver.getClass().getCanonicalName(), ex);
46+
}
47+
}
48+
});
49+
}
50+
51+
@Override
52+
public void contextDestroyed(ServletContextEvent event) {
53+
LOGGER.trace("contextDestroyed() 실행...");
54+
deregisterJdbcDrivers(event.getServletContext());
55+
}
56+
}

part07/ex06-board/src/main/webapp/WEB-INF/web-linux.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
1818
version="4.0">
1919

20+
<!-- JDBC 드라이버 해제 리스너, 맨 마지막에 실행되도록 최상단에 둔다.-->
21+
<listener>
22+
<listener-class>org.fp024.servlet.listener.JDBCDriverCleaner</listener-class>
23+
</listener>
24+
2025
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
2126
<context-param>
2227
<param-name>contextConfigLocation</param-name>

part07/ex06-board/src/main/webapp/WEB-INF/web.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
1919
version="4.0">
2020

21+
<!-- JDBC 드라이버 해제 리스너, 맨 마지막에 실행되도록 최상단에 둔다.-->
22+
<listener>
23+
<listener-class>org.fp024.servlet.listener.JDBCDriverCleaner</listener-class>
24+
</listener>
25+
2126
<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
2227
<context-param>
2328
<param-name>contextConfigLocation</param-name>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package org.fp024.servlet.listener;
2+
3+
import javax.servlet.ServletContext;
4+
import javax.servlet.ServletContextEvent;
5+
import javax.servlet.ServletContextListener;
6+
import javax.servlet.annotation.WebListener;
7+
import java.sql.DriverManager;
8+
import java.sql.SQLException;
9+
import java.util.Collections;
10+
import lombok.extern.slf4j.Slf4j;
11+
12+
@Slf4j
13+
@WebListener
14+
public class JDBCDriverCleaner implements ServletContextListener {
15+
protected void deregisterJdbcDrivers(ServletContext servletContext) {
16+
Collections.list(DriverManager.getDrivers())
17+
.forEach(
18+
driver -> {
19+
ClassLoader driverClassLoader = driver.getClass().getClassLoader();
20+
ClassLoader contextClassLoader = servletContext.getClassLoader();
21+
ClassLoader parentClassLoader =
22+
contextClassLoader != null ? contextClassLoader.getParent() : null;
23+
24+
LOGGER.debug(
25+
"### {} 드라이버의 클래스 로더: {}",
26+
driver.getClass().getCanonicalName(),
27+
driverClassLoader != null
28+
? driverClassLoader.getClass().getCanonicalName()
29+
: "Bootstrap ClassLoader");
30+
LOGGER.debug(
31+
"### 현재 서블릿 컨텍스트의 클래스 로더: {}",
32+
contextClassLoader != null
33+
? contextClassLoader.getClass().getCanonicalName()
34+
: "Bootstrap ClassLoader");
35+
LOGGER.debug(
36+
"### 현재 서블릿 컨텍스트의 부모 클래스 로더: {}",
37+
parentClassLoader != null
38+
? parentClassLoader.getClass().getCanonicalName()
39+
: "Bootstrap ClassLoader");
40+
41+
if (driverClassLoader == contextClassLoader
42+
|| driverClassLoader == parentClassLoader) {
43+
try {
44+
DriverManager.deregisterDriver(driver);
45+
LOGGER.info("### {} 드라이버 등록 해제", driver.getClass().getCanonicalName());
46+
} catch (SQLException ex) {
47+
LOGGER.warn("### {} 드라이버 등록 해제 실패", driver.getClass().getCanonicalName(), ex);
48+
}
49+
}
50+
});
51+
}
52+
53+
@Override
54+
public void contextDestroyed(ServletContextEvent event) {
55+
LOGGER.trace("contextDestroyed() 실행...");
56+
deregisterJdbcDrivers(event.getServletContext());
57+
}
58+
}

0 commit comments

Comments
 (0)