2

SpringをDBCPで使用しており、すべてのアプリケーションを再起動せずに、運用環境の構成が変更されたときにデータソースを更新する必要があります。

DBCPを使用せずにこれを行う場合は、現在開いているデータソースを強制的に閉じて、データソースの新しいインスタンスを開始します。

DBCP + Springを使用すると、それはできません。

誰かがそれが可能かどうか知っていますか?

4

1 に答える 1

8

プレーンDBCPにはそのようなサポートはないと思います。これは主に、アプリケーションの存続期間中にデータベース接続プロパティが変更されることはめったにないためです。また、古いデータソースによって提供された一部の接続がまだ開いていて、他の接続が新しい(更新された)接続からすでに提供されている場合は、移行時間を考慮する必要があります。

デコレータ/プロキシアプローチ

デコレータ/プロキシデザインパターンを活用したデータソースのカスタム実装を作成することをお勧めします。実装では、ターゲットデータソース(DBCPによって作成されたもの)を呼び出すだけで、ほとんどの場合、それ以上何もしません。ただし、ある種のrefresh()メソッドを呼び出すと、デコレータは以前に作成されたデータソースを閉じ、新しい構成で新しいデータソースを作成します。マルチスレッドについて覚えておいてください!

@Service
public class RefreshableDataSource implements DataSource {

    private AtomicReference<DataSource> target = new AtomicReference<DataSource>();

    @PostConstruct
    public void refresh() {
        target.set(createDsManuallyUsingSomeExternalConfigurationSource());
    }

    @Override
    public Connection getConnection() throws SQLException {
        return target.get().getConnection();
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return target.get().getConnection(username, password);
    }

    //Rest of DataSource methods

}

メソッドは次のcreateDsManuallyUsingSomeExternalConfigurationSource()ようになります。

private DataSource createDsManuallyUsingSomeExternalConfigurationSource() {
    DataSource ds = new org.apache.commons.dbcp.BasicDataSource();
    ds.setDriverClassName("org.h2.Driver");
    ds.setUrl(/*New database URL*/);
    ds.setUsername(/*New username*/);
    ds.setPassword(/*New password*/);
    return ds;
}

これは、SpringBeanとほぼ同等です。

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="org.h2.Driver" />
    <property name="url" value="jdbc:h2:mem:" />
    <property name="username" value="sa" />
    <property name="password" value="" />
</bean>

RefreshableDataSourceデータソース構成を動的/更新可能にしたいので、そのようなターゲットBeanをプロキシ/デコレータに注入することはできませんが、Springでは静的プロパティのみを注入できます。これは、ターゲットのインスタンスを作成するのはあなたの責任であることを意味しますBasicDataSourceが、ご覧のとおり、それは恐ろしいことではありません。

実際、私は考え直しました。SpringSpEL AFAIKを使用すると、XML構成から他のBeanのメソッドを呼び出すことができます。しかし、これは非常に幅広いトピックです。

JNDIアプローチ

別のアプローチは、JNDIをDataSource使用してホットデプロイメントをフェッチして使用することです(JBossとその*-ds.xmlファイルで機能します。

于 2011-02-15T18:18:10.827 に答える