Spring Frameworkの取扱い

基本情報

対応バージョン
Spring Framework 2.5.x 以上
basicInfoMap.dfprop
targetContainer を spring に設定

DI設定JavaConfig

JavaConfigの自動生成

1.1.x (Java8版) からは、DBFluteのコンポーネントをDI設定として JavaConfig がデフォルトで自動生成されます。 (targetContainer が spring であれば)

allcommon配下に生成されます。

e.g. 自動生成される JavaConfig のパッケージ @Directory
[APP ROOT]
 |-allcommon
 |  |-DBCurrent.java
 |  |-DBFluteBeansJavaConfig.java
 |  |-DBFluteConfig.java
 |  |-...
 |-bsbhv
 |-bsentity
 |-...

自動登録されるためのアノテーション

DBFluteBeansJavaConfig は、@Configuration と @ComponentScan が付与されているので、DBFluteの自動生成パッケージが Spring のスキャン対象であれば、自動的に登録されます。

e.g. 自動生成される JavaConfig, つまり DBFluteBeansJavaConfig.java @Java
@Configuration
@ComponentScan(value="org.docksidestage.dbflute.exbhv", lazyInit=true)
public class DBFluteBeansJavaConfig {

    // ===================================================================================
    //                                                                           Attribute
    //                                                                           =========
    @Autowired
    protected ApplicationContext _container;

    @Resource(name="dataSource")
    protected DataSource _dataSource; // name basis here for multiple DB

    // ===================================================================================
    //                                                                   Runtime Component
    //                                                                   =================
    @Bean(name="introduction")
    public DBFluteInitializer createDBFluteInitializer() { // no lazy for initialize-only component
        return new org.docksidestage.dbflute.allcommon.DBFluteInitializer(_dataSource);
    }

    @Bean(name="invokerAssistant")
    @Lazy
    public InvokerAssistant createImplementedInvokerAssistant() {
        ImplementedInvokerAssistant assistant = newImplementedInvokerAssistant();
        assistant.setDataSource(_dataSource);
        return assistant;
    }

    ...
}

DI設定xmlファイル

dbfluteBeans.xml の自動生成

1.0.x (Java6版) までは、DBFluteのコンポーネントをDI設定として xml がデフォルトで自動生成されます。 (targetContainer が spring であれば)

DBFluteは、Generateタスクにて DBFluteのコンポーネントが登録されている dbfluteBeans.xml を自動生成します。主には、Behavior と allcommon のクラスが登録されています。

dbfluteBeans.xml の登録

この dbfluteBeans.xml が アプリケーションのDI設定ファイルから参照されるように設定 することで、アプリケーションのコンポーネントからDBFluteのコンポーネント(主にBehavior)が利用できるようになります。

e.g. beanRefContext.xml にて dbfluteBeans.xml を参照 @beanRefContext.xml
<beans>
    <bean id="context" class="...support.ClassPathXmlApplicationContext">
        <constructor-arg>
            <list>
                <value>dbfluteBeans.xml</value>
                <value>jdbcBeans.xml</value>
            </list>
        </constructor-arg>
    </bean>
</beans>

dbfluteBeans.xml の名前を変更したい場合

DBFluteプロパティ dependencyInjectionMap.dfprop の dbfluteBeansFileName プロパティに、独自のファイル名を指定して再自動生成して下さい。(古いファイルは手動で削除)

DataSourceの連携

dataSourceというコンポーネント名

JavaConfig, xml 共に、デフォルトでは dataSource というコンポーネント名を想定してDIをしています。 DBFluteが、その DataSource から Connection を取得してDB接続します。

dataSourceという名前でない場合

アプリケーションで管理する DataSource のコンポーネント名が違う名前の場合は、 DataSource への参照を適切なものに変更してあげる必要があります。 (自動生成された JavaConfig や xml は、直接エディタで修正しても再自動生成時に上書きされますので意味がありません)

DBFluteプロパティ dependencyInjectionMap.dfprop の dbfluteBeansDataSourceName プロパティに、DataSourceの独自のコンポーネント名を指定して再自動生成して下さい。

複数DB対応のときは、よく利用することになるでしょう。

トランザクションの連携

DBFluteは、Spring で DI できる DataSource から、SQLのたびに Connection を取得しているだけなので、特に何も対策をしなければトランザクションはかかりませんが...

自動連携されるDBCP

DBFluteが認識している DBCP であれば、Spring の "スレッドトランザクション" 機構と自動的に連携し、トランザクションが効くようになります。

以下の DataSource であれば、設定なしでトランザクションが効きます。

commons-DBCP
org.apache.commons.dbcp. パッケージ
Tomcat-DBCP
org.apache.tomcat.jdbc.pool. パッケージ
commons-DBCP2
org.apache.commons.dbcp2. パッケージ (@since 1.1.8)
HikariCP
com.zaxxer.hikari. パッケージ (@since 1.1.8)

allcommonに自動生成される DBFluteInitializer の needsSpringTransactionalDataSource() にて判定されています。利用しているDBCPが対象かどうか?どのような仕組みになっているか?などなどコードを確認してみると良いでしょう。 (相当、ベタベタなやり方です)

e.g. DBFluteInitializer の needsSpringTransactionalDataSource(), 1.1.8 のとき @Java
protected boolean needsSpringTransactionalDataSource(String dataSourceFqcn) {
    return dataSourceFqcn.startsWith("org.apache.commons.dbcp.")
        || dataSourceFqcn.startsWith("org.apache.commons.dbcp2.")
        || dataSourceFqcn.startsWith("org.apache.tomcat.jdbc.pool.")
        || dataSourceFqcn.startsWith("com.zaxxer.hikari.");
}

ただ、この自動連携の仕組みは、DBFlute の DataSourceHandler を使って実現されています。 もし、アプリで DBFluteConfig 経由で独自の DataSourceHandler を設定したときは、自動連携の仕組みが上書きされますので、設定する DataSourceHandler は、デフォルトのものと同じ機能を持つ必要があります。(アプリで明示的に設定された方が優先されるため)

手動でDBCPと連携させる

自動的に連携されないDBCPを利用されている場合は、何かしら対策をする必要があります。 幾つかのやり方があります。

A. DBFluteInitialiezrをオーバーライド
littleAdjustmentMap.dfprop の extendedDBFluteInitializerClass を使って、DBFluteInitializer の継承クラスを登録することができます。needsSpringTransactionalDataSource()をオーバーライドして、認識させると良いでしょう。
B. DataSourceHandlerを設定
DBFluteConfig で、独自の DataSourceHandler を設定して、連携させると良いでしょう。
C. TransactionAwareDataSourceProxyを使う
アプリ側のDataSource本体の設定で、TransactionAwareDataSourceProxyを使うと良いでしょう。

Exampleのススメ

Spring Framework を使ったExample実装 dbflute-example-on-springboot があります。

ただ、Exampleとしてあまり整備が追いついていないので、プルリクを募集しています。