struts、spring、proxoolの統合使用に関するいくつかの問題
今日はプロジェクトをしていたときに何か問題があったので、自分が出たい原因を考えて、忘れないように記録しました.
私のプロジェクトはStruts、Spring、jdbcを採用しています.データベース接続プールはproxoolを使用しています.dao実装層コードを書くとき、すべての方法がデータベースの操作クラスに使用されることを発見し、spring注入方式でデータベース操作クラスをdao実装層に注入し、具体的なコードは以下の通りである.
データベース・オペレーション・クラスのコードは次のとおりです.
スプリングのプロファイルでは、次のように構成されています.
問題が発生しました.再配置すると、コンソールにデータベース・インスタンスを登録していないエラーが表示されます.Attempt to refer to a unregistered pool by its alias.......なぜこの間違いが起こったのかよく考えてみます.まず、プロジェクト内のspringのプロファイルがプラグインとしてロードされる理由を分析します.
strutsのプロファイルはtomcatの起動時にロードされます.これにより、すべてのactionインスタンスおよびbeanインスタンスがtomcatの起動時に初期化され、インスタンス化されます.データベース接続プールを取得する操作はDBOOperationで実現されます.
proxoolデータベースの接続プールは、関連するプロファイルをロードすることによってインスタンス化されなければならない.すなわちtomcatが起動するときにproxoolのプロファイルをロードしなければならない.以下はproxoolがwebにある.xmlの構成:
つまりproxoolになるしかない.xmlがメモリにロードされてから、データベース接続プールの操作ができます.springのプロファイルのロード時間とproxool.xmlのロード時間はほぼ同じ時間であり、以下に示すようにします.
したがってstrutsのプロファイルとproxoolのプロファイルは同時にロードされ、proxoolプロファイルがロードされない前にデータベースの操作でデータベースインスタンスが登録されていないエラーが報告されます.したがって、エラーを解決する方法はstrutsプロファイルのロードの優先度を変更し、2に変更することです.
皆さんの交流を学ぶことを歓迎します.間違ったところがあれば、皆さんに指摘してください.
私のプロジェクトはStruts、Spring、jdbcを採用しています.データベース接続プールはproxoolを使用しています.dao実装層コードを書くとき、すべての方法がデータベースの操作クラスに使用されることを発見し、spring注入方式でデータベース操作クラスをdao実装層に注入し、具体的なコードは以下の通りである.
package com.teabar.dao.impl;
import java.util.List;
import com.teabar.dao.BaseDao;
import com.teabar.db.util.DBOperation;
import com.teabar.db.util.DBRowProcessor;
import com.teabar.db.util.SqlGenerator;
public class BaseDaoImpl<T> implements BaseDao<T> {
public DBOperation dbOperate;
/**
*
*/
public void save(T entity, String tableName) {
try {
dbOperate.executeUpdate(SqlGenerator.insertSql(tableName, entity));
} catch (Exception e) {
e.printStackTrace();
} finally {
dbOperate.close();
}
}
@SuppressWarnings("unchecked")
public T findBy(T entity, String tableName) {
T bean = null;
try {
bean = (T) DBRowProcessor.setToBean(
dbOperate.executeQuery(
SqlGenerator.selectSql(tableName, entity)), entity.getClass());
} catch (Exception e) {
e.printStackTrace();
} finally {
dbOperate.close();
}
return bean ;
}
public void delete(T entity, String tableName) {
try {
dbOperate.executeUpdate(SqlGenerator.deleteSql(tableName, entity));
} catch (Exception e) {
e.printStackTrace();
}
}
public void update(String sql) {
try {
dbOperate.executeUpdate(sql);
} catch (Exception e) {
e.printStackTrace();
} finally {
dbOperate.close();
}
}
/**
* ,
*/
@SuppressWarnings("unchecked")
public T findBy(String tableName,T entity,String condition) {
T bean = null;
try {
bean = (T) DBRowProcessor.setToBean(
dbOperate.executeQuery(
SqlGenerator.selectSql(tableName, condition)), entity.getClass());
} catch (Exception e) {
e.printStackTrace();
} finally {
dbOperate.close();
}
return bean ;
}
/**
*
*/
public List<T> getAll(String tableName, T entitym) {
return null;
}
/**
*
*/
public int getTotalRecords(String tableName) {
return 0;
}
public void setDbOperate(DBOperation dbOperate) {
this.dbOperate = dbOperate;
}
}
データベース・オペレーション・クラスのコードは次のとおりです.
package com.teabar.db.util;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;
import com.teabar.db.DBConnectionManager;
import com.teabar.util.StringUtil;
public class DBOperation {
private DBConnectionManager connectManager;
private Connection connect;
private Vector<Statement> statementGroup;
private Vector<ResultSet> resultSetGroup;
public DBOperation(){
init();
}
public void init(){
this.connectManager = DBConnectionManager.getInstance();
this.connect = this.connectManager.getConnection();
this.statementGroup = new Vector<Statement>();
this.resultSetGroup = new Vector<ResultSet>();
}
public Connection getConnection() {
return this.connect;
}
public Statement getStatement() {
try {
return this.connect.createStatement();
} catch (SQLException e) {
}
return null;
}
public boolean getAutoCommit() throws SQLException{
return this.connect.getAutoCommit();
}
public void setAutoCommit(boolean autoCommit) {
try {
this.connect.setAutoCommit(autoCommit);
} catch (SQLException e) {
}
}
public ResultSet executeQuery(String queryString) throws SQLException{
if(StringUtil.checkNull(queryString))throw new SQLException("sql is null");
Statement localStatement = this.connect.createStatement();
ResultSet localResultSet = localStatement.executeQuery(queryString);
resultSetGroup.add(localResultSet);
statementGroup.add(localStatement);
return localResultSet;
}
public int executeUpdate(String queryString) throws SQLException {
if(StringUtil.checkNull(queryString))throw new SQLException("sql is null");
Statement localStatement = this.connect.createStatement();
this.statementGroup.add(localStatement);
return localStatement.executeUpdate(queryString);
}
public void close() {
try {
if(resultSetGroup!=null) {
for(int i=0; i<resultSetGroup.size(); i++) {
resultSetGroup.get(i).close();
}
resultSetGroup = new Vector<ResultSet>();;
}
if(statementGroup!=null) {
for(int i=0; i<statementGroup.size(); i++) {
statementGroup.get(i).close();
}
statementGroup = new Vector<Statement>();
}
this.connectManager.closeConnection(this.connect);
} catch (SQLException e) {
}
}
}
スプリングのプロファイルでは、次のように構成されています.
......
<bean id="dbOperate" class="com.teabar.db.util.DBOperation"/>
<bean name="/login" class="com.teabar.web.user.action.LoginAction" scope="request">
<property name="menberService">
<ref bean="menberService"/>
</property>
</bean>
<bean id="menberService" class="com.teabar.service.user.MenberService">
<property name="menberDao">
<ref bean="menberDao"/>
</property>
</bean>
<bean id="menberDao" class="com.teabar.dao.impl.user.MenberDaoImpl">
<property name="dbOperate">
<ref bean="dbOperate"/>
</property>
</bean>
......
問題が発生しました.再配置すると、コンソールにデータベース・インスタンスを登録していないエラーが表示されます.Attempt to refer to a unregistered pool by its alias.......なぜこの間違いが起こったのかよく考えてみます.まず、プロジェクト内のspringのプロファイルがプラグインとしてロードされる理由を分析します.
<plug-in
className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml"/>
</plug-in>
strutsのプロファイルはtomcatの起動時にロードされます.これにより、すべてのactionインスタンスおよびbeanインスタンスがtomcatの起動時に初期化され、インスタンス化されます.データベース接続プールを取得する操作はDBOOperationで実現されます.
......
public DBOperation(){
init();
}
public void init(){
this.connectManager = DBConnectionManager.getInstance();
this.connect = this.connectManager.getConnection();
this.statementGroup = new Vector<Statement>();
this.resultSetGroup = new Vector<ResultSet>();
}
......
proxoolデータベースの接続プールは、関連するプロファイルをロードすることによってインスタンス化されなければならない.すなわちtomcatが起動するときにproxoolのプロファイルをロードしなければならない.以下はproxoolがwebにある.xmlの構成:
<servlet>
<servlet-name>ServletConfigurator</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>
つまりproxoolになるしかない.xmlがメモリにロードされてから、データベース接続プールの操作ができます.springのプロファイルのロード時間とproxool.xmlのロード時間はほぼ同じ時間であり、以下に示すようにします.
......
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<!-- , , -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>ServletConfigurator</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>
......
したがってstrutsのプロファイルとproxoolのプロファイルは同時にロードされ、proxoolプロファイルがロードされない前にデータベースの操作でデータベースインスタンスが登録されていないエラーが報告されます.したがって、エラーを解決する方法はstrutsプロファイルのロードの優先度を変更し、2に変更することです.
皆さんの交流を学ぶことを歓迎します.間違ったところがあれば、皆さんに指摘してください.