2

我正在从事这个项目,该项目已经通过了许多编码人员的手。该应用程序分为两部分 - Web 和 Batch。Web 部件为用户提供了一个基本的 UI 来设置一些配置。它使用 JDBC/JNDI/非 Spring,DAO 是基于此编写的。

批处理部分生成 PDF、PostScripts、XML 等文件。这部分使用 JDBC/Spring,DAO 是基于此编写的。

现在只有一个代码库,但代码被分隔在几个文件夹或模块中 - Web(war 文件)、Batch(从 .bat 或 .sh 运行的 Java 应用程序)和 Commons(jar 文件)。尽管 Web 和 Batch 都使用相同的 Commons jar 文件,但 DAO 非常分散,以至于很难编写一个具有共享 DAO 的新模块,该模块既可用于部署在 Web 和批处理中的代码。

由于我将长期支持这个项目,我决定开始改进。首先,以某种方式组合所有 DAO,新模块将使用一组统一的 DAO 和旧模块来使用现有的脆弱代码。

下面,com.abc.core2.dao.ABCDAO 将保存对单个 DataSource 实例的引用,并在 web 或批处理中使用它来从数据库获取连接。DataSource 对象取自每个模块的核心 DAO,并将其缓存在 ABCDAO.dataSource 实例变量中。

有没有人做过这样的事情?在重新启动应用程序之前保留单个 DataSource 对象有什么问题吗?

不过,这个变化仍然是一个原型。我的客户将其他一些简单的更改外包给了一群人。

通用(jar 文件)

package com.abc.core2.dao;
public class ABCDAO {
    private static ABCDAO abcdao = new ABCDAO();
    private DataSource dataSource;
    public void setInternalDataSource(DataSource dataSource) {this.dataSource = dataSource;}
    public DataSource getInternalDataSource() { return this.dataSource; }
    public static ABCDAO getInstance() { return this.abcdao; }
    ...
}
public class NewModuleJdbcDao implements NewModuleDAO {
    ...
    public List<XYZBean> getXYZ(SearchBean sb) {
        Connection con = ABCDAO.getInstance().getInternalDataSource().getConnection();
        ...
        con.close();
        return listOfXYZBeans;
    }
}

批量申请

import com.abc.core2.dao.ABCDAO;
public abstract InformixBaseDAO extends ABCBaseDAO { 
    {
        // via Spring JDBC XML configuration
        ABCDAO.getInstance().setDataSource(NewConnectionPooler.getInstance().dataSource()); 
    }
    public Connection getConnection() throws SQLException {
        // pre-existing method. It does NewConnectionPooler.getInstance().getConnection()
        ...
        return connection;
    }
}

// Use same NewModuleJdbcDao in Web application
public class NewModuleClass001 {

    public void show(SearchBean bean) { 
        ...
        NewModuleJdbcDao dao = new NewModuleJdbcDao();
        List<XYZBean> list = dao.getXYZ(bean);
        ...
    }
}

Web应用程序

import com.abc.core2.dao.ABCDAO;
public class DBConnection {
    private static DataSource dataSource = null;
    {
        if(dataSource == null) {
            dataSource = ServiceLocator.getInstance().getDataSource(...); // via JNDI
            ABCDAO.getInstance().setDataSource(dataSource);
        }
    }
    public static Connection() {

        // Spring JDBC 
        ... 
    }
}

// Use same NewModuleJdbcDao in Web application
public class NewModuleClass001 {

    public void show(SearchBean bean) { 
        ...
        NewModuleJdbcDao dao = new NewModuleJdbcDao();
        List<XYZBean> list = dao.getXYZ(bean);
        ...
    }
}
4

1 回答 1

0

我一直在实践中使用这种策略,并且不熟悉基于该解决方案的任何问题。如果您还使用 spring 将池数据源定义为应用程序范围的单例 bean,并将其注入您的模块中。

于 2013-02-26T17:02:38.657 回答