読者です 読者をやめる 読者になる 読者になる

かんがるーさんの日記

最近自分が興味をもったものを調べた時の手順等を書いています。今は Spring Boot をいじっています。

Spring Boot + Spring Integration でいろいろ試してみる ( その6 )( AcceptOnceFileListFilter をセットしていないはずの FileReadingMessageSource で同じファイルが2度処理されない理由とは? )

概要

記事一覧はこちらです。

Spring Boot + Spring Integration でいろいろ試してみる ( その5 )( 監視しているディレクトリに置かれた Excel ファイルのデータを DB に登録する → 処理が終わったら Excel ファイルを削除/移動する2 ) の続きです。

FileReadingMessageSource に AcceptOnceFileListFilter をセットしていないにも関わらず、in ディレクトリに同じファイルをコピーしても2回目以降は処理されない原因を調査します。

参照したサイト・書籍

目次

  1. 生成した FileReadingMessageSource のインスタンスの内容を Debugger で見てみる
  2. どこで AcceptOnceFileListFilter をセットしているのか?
  3. AcceptOnceFileListFilter を外して同じファイルが処理されることを確認する

手順

生成した FileReadingMessageSource のインスタンスの内容を Debugger で見てみる

src/main/java/ksbysample/eipapp/dirchecker/eip/endpoint の下の InDirChecker.java の inDirFileReadingMessageSource メソッドの以下の場所に Breakpoint を設定します。

f:id:ksby:20160910065332p:plain

Debug 実行して Breakpoint で処理が止まった後、生成した FileReadingMessageSource のインスタンスを見てみると fileFilters に IgnoreHiddenFileListFilter, AcceptOnceFileListFilter が既にセットされていました。

f:id:ksby:20160910070639p:plain

どこで AcceptOnceFileListFilter をセットしているのか?

FileReadingMessageSource クラスのソースを見ると、フィールド scanner に初期値として DefaultDirectoryScanner クラスのインスタンスをセットしており、

f:id:ksby:20160910072807p:plain

DefaultDirectoryScanner クラスのソースを見ると、コンストラクタで AcceptOnceFileListFilter をセットしていました。

f:id:ksby:20160910073129p:plain

再度 FileReadingMessageSource クラスのソースを見ると onInit メソッドでフィールド filter がセットされている場合には scanner.setFilter メソッドを呼び出して scanner の filter の設定を変更するようになっていました。

f:id:ksby:20160910073908p:plain

結論としては、

  • filter は FileReadingMessageSource クラスのフィールド scanner にセットされているものが使用されます。
  • デフォルトでは scanner には DefaultDirectoryScanner クラスのインスタンスがセットされ、DefaultDirectoryScanner クラスのコンストラクタで AcceptOnceFileListFilter がセットされます。
  • FileReadingMessageSource#setFilter メソッドを呼び出して独自の filter をセットすれば、scanner の filter はその内容に上書きされます ( 追加ではありません )。

AcceptOnceFileListFilter を外して同じファイルが処理されることを確認する

AcceptOnceFileListFilter を外す方法は2つあります。

  • 完全に filter を空にしたいならば FileReadingMessageSource#setScanner メソッドを呼び出して filter が空の DirectoryScanner インターフェースの実装クラスを実装してセットします。
  • filter が空にしないならば FileReadingMessageSource#setFilter メソッドを呼び出して上書きする filter をセットします。

今回は IgnoreHiddenFileListFilter はセットしておきたいので FileReadingMessageSource#setFilter メソッドを呼ぶ方法で試してみます。

src/main/java/ksbysample/eipapp/dirchecker/eip/endpoint の下の InDirChecker.java の inDirFileReadingMessageSource メソッドで、 IgnoreHiddenFileListFilter だけがセットされた filter をセットします。

    @Bean
    public FileReadingMessageSource inDirFileReadingMessageSource() {
        FileReadingMessageSource source = new FileReadingMessageSource();
        source.setDirectory(Paths.get(IN_DIR_PATH).toFile());

        CompositeFileListFilter<File> filter = new CompositeFileListFilter<>();
        filter.addFilter(new IgnoreHiddenFileListFilter());
        source.setFilter(filter);

        return source;
    }

事前準備として user_info, user_role テーブルを以下の状態にします。

f:id:ksby:20160910205042p:plain

in ディレクトリ、error ディレクトリは空にします。

f:id:ksby:20160910205205p:plain

bootRun タスクを実行して Tomcat を起動します。

f:id:ksby:20160910205505p:plain

in ディレクトリに TestData01.xlsx をコピーするとファイルが正常処理されて削除されました。

f:id:ksby:20160910205623p:plain ↓↓↓ f:id:ksby:20160910205723p:plain

user_info, user_role テーブルを見るとデータが登録されていることが確認できます。

f:id:ksby:20160910205834p:plain

再び in ディレクトリに TestData01.xlsx をコピーすると今度もファイルが正常処理されて削除されました。

f:id:ksby:20160910210003p:plain ↓↓↓ f:id:ksby:20160910210112p:plain

user_info, user_role テーブルを見ると更にデータが登録されていることが確認できます。

f:id:ksby:20160910210229p:plain

同じファイルを in ディレクトリにコピーしても処理されることが確認できました。Ctrl+F2 を押して Tomcat を停止します。

user_info, user_role テーブルに追加されたデータは削除します。また今回の変更は commit しません。

ソースコード

履歴

2016/09/10
初版発行。