Spring3中使用proxool,会出现无法加载proxool的情况。
由于web.xml文件中的加载顺序是:
(1)<context-param>
(2)<listener>
(3)<filter>
(4)<servlet>
因为spring3是采用<listener>进行启动(如下:)
<!-- spring资源文件位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/applicationContext-*.xml</param-value>
</context-param>
<!-- 启动spring -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
所以如果我们采用proxool提供的<servlet>进行加载的话,因为先启动了spring,造成proxool无法加载的问题。
分析以上原因,提出解决方案:
(1)向proxool靠拢:因为proxool只提供了<servlet>的加载方式,如果我们的proxool和spring都采用<servlet>进行加载,且proxool优先于spring加载,如下:
<!-- 启动连接池 -->
<servlet>
<servlet-name>proxoolServletConfigurator</servlet-name>
<servlet-class>org.logicalcobwebs.proxool.configuration.ServletConfigurator</servlet-class>
<init-param>
<param-name>xmlFile</param-name>
<param-value>WEB-INF/proxool.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>
org.springframework.web.context.ContextLoaderServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
但是。。。spring3不再提供<servlet>的加载方式(,可以自定义spring的<servlet>加载方式)。
(2)向spring靠拢:因为spring只提供了<listener>的加载方式,我们可以自定义listener,让proxool采用listener进行加载,且先于spring加载,如下:
<!-- 启动proxool -->
<context-param>
<param-name>xmlFile</param-name>
<param-value>WEB-INF/proxool.xml</param-value>
</context-param>
<listener>
<listener-class>com.ys.listener.ProxoolListener</listener-class>
</listener>
<!-- spring资源文件位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/applicationContext-*.xml</param-value>
</context-param>
<!-- 启动spring -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
自定义ProxoolListener.java:
public class ProxoolListener implements ServletContextListener {
// private static final Logger logger = Logger.getLogger(ProxoolListener.class);
private static final String XML_FILE_PROPERTY = "xmlFile";
private static final String PROPERTY_FILE_PROPERTY = "propertyFile";
private static final String AUTO_SHUTDOWN_PROPERTY = "autoShutdown";
private boolean autoShutdown = true;
@Override
public void contextDestroyed(ServletContextEvent arg0) {
System.out.println("destroy database pool....");
}
@Override
public void contextInitialized(ServletContextEvent contextEvent) {
ServletContext context = contextEvent.getServletContext(); // 对应servlet的init方法中ServletConfig.getServletContext()
String appDir = contextEvent.getServletContext().getRealPath("/");
Properties properties = new Properties();
Enumeration<?> names = context.getInitParameterNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
String value = context.getInitParameter(name);
if (name.equals(XML_FILE_PROPERTY)) {
try {
File file = new File(value);
if (file.isAbsolute()) {
JAXPConfigurator.configure(value, false);
} else {
JAXPConfigurator.configure(appDir + File.separator + value, false);
}
} catch (ProxoolException e) {
// logger.error("Problem configuring " + value, e);
}
} else if (name.equals(PROPERTY_FILE_PROPERTY)){
try {
File file = new File(value);
if (file.isAbsolute()) {
PropertyConfigurator.configure(value);
} else {
PropertyConfigurator.configure(appDir + File.separator + value);
}
} catch (ProxoolException e) {
// logger.error("Problem configuring " + value, e);
}
} else if (name.equals(AUTO_SHUTDOWN_PROPERTY)) {
autoShutdown = Boolean.valueOf(value).booleanValue();
} else if (name.startsWith("jdbc")) {
properties.setProperty(name, value);
}
}
if (properties.size() > 0) {
try {
PropertyConfigurator.configure(properties);
} catch (ProxoolException e) {
// logger.error("Problem configuring using init properties", e);
}
}
}
}
问题解决。