rich client / community javafx in spring - oracle.com ·...

4
ORACLE.COM/JAVAMAGAZINE NOVEMBER/DECEMBER 2012 JAVA TECH 35 COMMUNITY JAVA IN ACTION ABOUT US blog //rich client / J avaでサーバー・サイドの開発 を行ったことがある開発者で あれば、Javaエンタープライズ Webアプリケーションの構築や強 化のためにSpring Framework の何らかの要素を使用した経験 があるのではないでしょうか。 Spring Frameworkには、強力な 依存性注入(DI)システム、Web 版のモデル・ビュー・コントローラ (MVC)フレームワーク、さらには データベース・アクセスからセキュ リティ認証制御までのあらゆる機 能に対応するヘルパー・ライブラリ が含まれています。 一方、JavaFXでは2.xリリース でPure Java APIが提供され、 SpringのようなJavaライブラリ の統合が非常に容易になりまし た。Spring Frameworkをクライ アント上で利用した場合、次のよ うなメリットがあります。 UIの制御の反転制御の反転 (IoC)は、タスクの実行をその タスクの実装から切り離すた めに用いられるオブジェクト指 向の技法です。UIの場合、 IoC はスタンドアロン・モジュール の作成に非常に便利です。スタ ンドアロン・モジュー ルを作 成 して、Springなどの依存性管 理フレームワークでそれらの モジュールの関係をインジェク ションできます。 1行で記述できるWebサービ スクライアントとサーバーで 互換性のあるRESTフレーム ワークを利用することで、同じモ デル・オブジェクトを再利用し、 データの取得、作成、削除、更新 を行うWebサービスの呼び出し を1行の文で実装できます。 認証と認可クライアント上で の認証/認可機能を一から開発 するのではなく、サーバー要求 のセキュリティ保護に使用して いるものと同じ認証メカニズム を利用できます。また、詳細な 認可テストを行って、権限に応 じてUIの外観や操作性を変更 することもできます。 非常に単純なアプリケーション の場合、これらの機能によって得ら れるメリットは、新しいライブラリの 学習や統合にかかるコストを大き く上回るほどではないかもしれま せん。一方で、複数の画面で構成さ れ、バックエンド・サーバーへの接続 やユーザーの認証を伴う大規模な アプリケーションを構築する場合に は、アプリケーションが大規模で複 雑であればあるほど、得られるメリッ トも飛躍的に増します。 本記事では、実際のアプリ ケ ーションの 中 でこうしたメリッ トを 実 証 す るた め に 、S p r i n g FrameworkとJavaFXを組み合 わせたアプリケーションとして、フ ロントエンド・コンポーネントとバッ クエンド・コンポ ー ネントの 両 方 を含む顧客データアプリケーショ ンを一から構築します。この顧客 データアプリケーションには、ログ イン・ユーザーの認証用モジュー ル、SpringのRestTemplate使用したバックエンドのWebサー ビス統合機能、ロール別の適切な 権限に基づく作成/削除操作が含 まれます。アプリケーションの最終 的な外観は図1のようになります。 全2回のシリーズを通してこの サンプルを完成させていきます が、GitHubではすでにサンプル の完全なソースコードを閲覧でき ます。また、ダウンロードして実行 することも可能です。 クライアントでSpringフレームワークを使用する理由 STEPHEN CHIN BIO パート1 JavaFX in Spring 図1 Stephen Chin (@steveon java) オラクルの Java Technology Ambassador。 JavaFX の代表的技術文 献である Pro JavaFX 2 (Apress、2012 年) を共同執筆。Devoxx、 CodeMash、OSCON、 J-Fall、GeeCON、 JAZOON、JavaOne など多くの Java カンファ レンスで取り上げられ、 Rock Star アワードを 2 度受賞。

Upload: trinhtuyen

Post on 15-Jul-2019

218 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: rich client / COMMUNITY JavaFX in Spring - oracle.com · (MVC)フレームワーク、さらには データベース・アクセスからセキュ リティ認証制御までのあらゆる機

ORACLE.COM/JAVAMAGAZINE NOVEMBER/DECEMBER 2012

JAVA TECH

35

COMMUNITY

JAVA IN

ACTION

ABOUT US

blog

//rich client /

Javaでサーバー・サイドの開発を行ったことがある開発者で

あれば、JavaエンタープライズWebアプリケーションの構築や強化のためにSpring Frameworkの何らかの要素を使用した経験があるのではないでしょうか。Spring Frameworkには、強力な依存性注入(DI)システム、Web版のモデル・ビュー・コントローラ(MVC)フレームワーク、さらにはデータベース・アクセスからセキュリティ認証制御までのあらゆる機能に対応するヘルパー・ライブラリが含まれています。一方、JavaFXでは2.xリリース

でPure Java APIが提供され、SpringのようなJavaライブラリの統合が非常に容易になりました。Spring Frameworkをクライアント上で利用した場合、次のようなメリットがあります。

■ UIの制御の反転̶制御の反転(IoC)は、タスクの実行をそのタスクの実装から切り離すために用いられるオブジェクト指向の技法です。UIの場合、IoCはスタンドアロン・モジュールの作成に非常に便利です。スタンドアロン・モジュールを作成

して、Springなどの依存性管理フレームワークでそれらのモジュールの関係をインジェクションできます。

■ 1行で記述できるWebサービス̶クライアントとサーバーで互換性のあるRESTフレームワークを利用することで、同じモデル・オブジェクトを再利用し、データの取得、作成、削除、更新を行うWebサービスの呼び出しを1行の文で実装できます。

■ 認証と認可̶クライアント上での認証/認可機能を一から開発するのではなく、サーバー要求のセキュリティ保護に使用しているものと同じ認証メカニズムを利用できます。また、詳細な認可テストを行って、権限に応じてUIの外観や操作性を変更することもできます。非常に単純なアプリケーション

の場合、これらの機能によって得られるメリットは、新しいライブラリの学習や統合にかかるコストを大きく上回るほどではないかもしれません。一方で、複数の画面で構成され、バックエンド・サーバーへの接続やユーザーの認証を伴う大規模なアプリケーションを構築する場合に

は、アプリケーションが大規模で複雑であればあるほど、得られるメリットも飛躍的に増します。本記事では、実際のアプリ

ケーションの中でこうしたメリットを実証するために、Spr i ng FrameworkとJavaFXを組み合わせたアプリケーションとして、フロントエンド・コンポーネントとバックエンド・コンポーネントの両方を含む顧客データアプリケーションを一から構築します。この顧客データアプリケーションには、ログ

イン・ユーザーの認証用モジュール、SpringのRestTemplateを使用したバックエンドのWebサービス統合機能、ロール別の適切な権限に基づく作成/削除操作が含まれます。アプリケーションの最終的な外観は図1のようになります。全2回のシリーズを通してこの

サンプルを完成させていきますが、GitHubではすでにサンプルの完全なソースコードを閲覧できます。また、ダウンロードして実行することも可能です。

クライアントでSpringフレームワークを使用する理由

STEPHEN CHIN

BIO

パート1

JavaFX in Spring

図1

Stephen Chin (@steveon java) オラクルの Java Technology Ambassador。 JavaFXの代表的技術文献であるPro JavaFX 2 (Apress、2012年)を共同執筆。Devoxx、CodeMash、OSCON、J-Fall、GeeCON、JAZOON、JavaOneなど多くのJavaカンファレンスで取り上げられ、Rock Star アワードを2度受賞。

Page 2: rich client / COMMUNITY JavaFX in Spring - oracle.com · (MVC)フレームワーク、さらには データベース・アクセスからセキュ リティ認証制御までのあらゆる機

ORACLE.COM/JAVAMAGAZINE NOVEMBER/DECEMBER 2012

JAVA TECH

36

COMMUNITY

JAVA IN

ACTION

ABOUT US

blog

//rich client / アプリケーション・テンプレートSpringを基盤としたサーバー・サイドの開発に関わったことがある方は、Springを使用する新規アプリケーションの設定が簡単であることをご存じでしょう。JARファイル(またはMavenの依存関係)を追加し、web.xmlファイルにコードを数行追加するだけです。一方、クライアントでは、メイン・クラス

から手動でSpringランタイムを起動する必要があります。本項で作成するアプリケーション・テンプレートには、スレッドセーフの状態でJavaFXランタイムとSpringランタイムを起動する方法が示されています。その前にまずは、スレッドセーフにする

理由を理解するために、JavaFXのスレッドに関する背景情報を少し確認しましょう。JavaFXには、目的の異なる2種類の

スレッドがあります。 ■ アプリケーション・スレッド̶JavaFXのシーン・グラフに対するすべての操作と、トップレベル・ウィンドウを使用するオブジェクトの作成を行うスレッド。Swingのイベント・ディスパッチ・スレッドに相当します(ただし、同じスレッドというわけではないため、Swingとの相互運用のためのコードでは注意してください)。

■ 描画スレッド̶表示するシーンを準備するために、グラフィックが変化するたびに呼び出されるスレッド。グラフィックの変化としては 、アニメーション/CSS/レイアウトの処理、シーン・グラフと描画ツリーの同期、マウス・ホバーの状態の更新などがあります。ほとんどの場合、描画スレッドはシー

ンのバックグラウンドで実行され、開発

者が考慮する必要はありません。一方、アプリケーション・スレッドに対しては少し注意が必要です。JavaFXでアプリケーション・コードを

呼び出す場合は、startやstopといったアプリケーションのメソッド内であろうとイベント・ハンドラ内であろうと、その呼び出しは必ずアプリケーション・スレッド上で実行されます。そのため、アプリケーション側で新しいJavaFXオブジェクトを安全に作成して、シーン・グラフを自由に操作できます。ただし、アプリケーションをメイン・スレッドで実行する場合や、独自のスレッドを生成する場合は、描画ツリーに影響を及ぼすJavaFXのメソッドを呼び出さないように注意してください。呼び出した場合は、例外やデッドロックが発生することや、さらに悪い結果につながることもあります。リスト1(CustomerModel.java)

は、CustomerAppデモ・プロジェクトのメイン・アプリケーション・クラスです。JavaFXアプリケーション・スレッドの初期化や、JavaクラスからのSpring設定のロードを行っています。startメソッドの手前までは、定型的な

JavaFXアプリケーションに非常に近いコードです。startメソッドでは、SpringのApplicationContextを初期化しています。その際、Java設定を使用する場合は新しいAnnotationConfigApplication Contextを作成し、XMLからロードする場合はClassPathXmlApplication Contextを作成します。ここでは、Spring Framework 3.0

で新たに導入されたアノテーションベースのJava設定サポートを利用することを強くお勧めします。コード内で設定を

定義できる利便性があるだけでなく、SpringのXMLベース設定で実現される強力な機能や容易なデバッグ処理もそのまま活用できるためです。本記事のサンプルではアノテーションベースとXMLベースの設定、両方のスタイルを組み合わせて宣言しています。アプリケーションの目的に応じて、こういった組み合わせた方法も便利です。。アプリケーションのメイン・メソッド内

でSpringのコンテキストを初期化したくなるかもしれませんが、これは非常に危険です。Springのコンテキストをロードした場合に、Springを起動したスレッドにJavaFXのオブジェクトがロードされる可能性があるからです。Stage、Popup、Menuなどのトップレベル・ウィ

ンドウを使用するJavaFXオブジェクトを作成した場合は、この問題を示す例外が発生します。一方、リスト1のstartメソッドはJavaFXアプリケーション・スレッド上で呼び出されます。そのため、任意の型のJavaFXオブジェクトを安全に作成し、それらのオブジェクトをSpring設定内からでもシーン・グラフに追加できます。リスト1のサンプルでは、Screens

Configurationというサブ設定クラスをロードし、その設定オブジェクトにstageを設定して、ログイン・ダイアログ・ボックスを表示するメソッドを呼び出しています。

Download all listings in this issue as text

public class CustomerApp extends Application { public static void main(String[] args) { launch(args); }

@Override public void start(Stage stage) throws Exception { ApplicationContext context = new AnnotationConfigApplicationContext CustomerAppConfiguration.class); ScreensConfiguration screens = context.getBean(ScreensConfiguration.class); screens.setPrimaryStage(stage); screens.loginDialog().show(); }}

LISTING 1

Page 3: rich client / COMMUNITY JavaFX in Spring - oracle.com · (MVC)フレームワーク、さらには データベース・アクセスからセキュ リティ認証制御までのあらゆる機

ORACLE.COM/JAVAMAGAZINE NOVEMBER/DECEMBER 2012

JAVA TECH

37

COMMUNITY

JAVA IN

ACTION

ABOUT US

blog

//rich client / DIによるUIのモジュール化以上でSpringをロードできるようになりました。次にSpringの一部の機能を利用して、JavaFXアプリケーションをモジュール化します。この顧客データアプリケーションは最終的に次の画面で構成されます。

■ ログイン画面 ■ データ表示画面 ■ エラー画面 ■ 「顧客の追加」画面これらの画面は、それぞれ別個の

JavaFXクラスまたはFXMLファイルとして実装します。また、他の画面の参照(ナビゲーションを行う場合)とモデル(データ・アクセスやデータの更新が発生する場合)も必要になります。さらに、最初の利用時に画面が作成され、かつ、画面ごとに一度に1インスタンスしか保持しないようにします。リスト 2 aと 2 b( S c r e e n s

Configuration.java)は、各画面をそれぞれ別個のBeanとして定義するSpring設定クラスです。ScreensConfigurationファイルで

は、@Beanアノテーションを使用して、各画面および関連コントローラを別個のBeanとして定義しています。また、一部のBean(本記事のサンプルでは、ダイアログ・ボックスを表示するBeanのすべて)を@Scope("prototype")アノテーションを使用して定義しています。これにより、インスタンスを取得しようとするたびに新しいインスタンスが作成されます。一方、メインのデータ表示画面のスコープはデフォルトの"singleton"です。そのため、メソッドを何回呼び出したとしても、メイン画面はアプリケーション全

体で1つのみ存在します。また、設定クラス全体に対して@Lazy

アノテーションを指定しています。そのため、それぞれのBeanは初回のアクセス時まで作成されません。ただし、@Lazyアノテーションを指定しただけでは、アプリケーションの起動時にBeanが作成されないことを保証するためには不十分です。複数の画面の間に直接リンクがある場合は、最初の画面がロードされた際に、他の参照先の画面もすべて連鎖的にロードされます。全画面が一度にロードされないよ

うにするには、リンクする画面の参照をインジェクションするのではなく、ScreensConfigurationクラスの参照を渡します。この方法によって、別のScreensConfigurationインスタンスを設定して実装を入れ替えるという柔軟性を確保しながら、特定の画面をロードするメソッドが呼び出されるまでオブジェクトの作成を遅らせることができます。モ デ ル お よ び W e b サ ー ビ ス

に 関 す る そ の 他 の 設 定 は 、別のクラス・ファイルに定義します(CustomerAppConfiguration.j a v a、リスト3参照)。このクラスでは、アノテーションを使用してScreensConfigurationをロードしています。

FXMLへのコントローラのインジェクション前項では複数の画面を、Javaクラス・ファイルまたはFXMLとして定義しました。Springによって初期化されたコントローラをJavaオブジェクトに割り当てることは非常に簡単ですが、同様の

Download all listings in this issue as text

@Configuration@Lazypublic class ScreensConfiguration { private Stage primaryStage;

public void setPrimaryStage(Stage primaryStage) { this.primaryStage = primaryStage; }

public void showScreen(Parent screen) { primaryStage.setScene(new Scene(screen, 777, 500)); primaryStage.show(); }

@Bean CustomerDataScreen customerDataScreen() { return new CustomerDataScreen(customerDataScreenController()); }

@Bean CustomerDataScreenController customerDataScreenCon-troller() { return new CustomerDataScreenController(this); }

@Bean @Scope("prototype") FXMLDialog errorDialog() { return new FXMLDialog(errorController(),getClass().getResource("Error.fxml"), primaryStage, StageStyle.UNDECORATED); }

LISTING 2a LISTING 2b

Page 4: rich client / COMMUNITY JavaFX in Spring - oracle.com · (MVC)フレームワーク、さらには データベース・アクセスからセキュ リティ認証制御までのあらゆる機

ORACLE.COM/JAVAMAGAZINE NOVEMBER/DECEMBER 2012

JAVA TECH

38

COMMUNITY

JAVA IN

ACTION

ABOUT US

blog

//rich client /

コントローラをFXMLに割り当てることは、JavaFX 2.0リリースでは不可能でした。しかし、JavaFX 2.1リリースでは、この問題を解決して各種IoCフレームワークに対応するためのAPIが追加されました。ここでの各種IoCフレームワークには、コンテキストと依存性の注入(CDI)、Guiceなどのほか、言うまでもなくSpringも含まれます。例として、ErrorDialogの定義を詳し

く見てみます。ビューとコントローラは両方ともScreensConfigurationクラス内で作成されます。クラスを作成するコードをリスト4に示します。errorControllerが、FXMLDialogク

ラスに依存関係としてインジェクションされていることにお気づきでしょうか。FXMLDialogは、FXMLファイルのロード・ロジックとコントローラ・オブジェクトのインジェクション・ロジックをまとめてカプセル化したカスタム・クラスです。FXMLDialogのソース・コード全体をリスト5(FXMLDialog.java)に示します。FXMLDialogクラスは、FXMLファ

イルを新しいダイアログ(Stage)としてロードするために通常必要となるコードの一部を一般化したものです。特に、コントローラのインジェクションにとって重要な部分は、loader.setControl-lerFactory()の呼び出しです。この呼び出しにより、インナー・クラスを作成

し、その中で、パラメータとして渡されたコントローラを返しています。このようにコントローラを作

成してインジェクションするテクニックによって、コントロー

ラがSpringで管理される他のあらゆるオブジェクトと同様に扱われます。その結果、DIや「Autowiring」(自動関連付け)などのフレームワークの機能を利用できます。ErrorControllerのソース・コード全体をリスト6(ErrorController.j ava)に示します。また、基底インタフェースのDialogControllerはリスト7(DialogController.java)のとおりです。

本記事のFXML UIはSceneBuilderを 使 用 し て 作 成 し ま し た 。SceneBuilderは、JavaFXの各種コンポーネントについて学習し、UIのモックアップを簡単に作成できる優れたビジュアル・ツールです。作成した最終的なエラー・ダイアログ・ボックスは図2のようになります。

まとめ本記事では、SpringとJavaFXを組み合わせて使用するアプリケーションのテンプレートを紹介しました。このテンプレートは各自のプロジェクトで再利用できます。Springの設定とDIを利用するだけで、Pure Javaでの開発を基盤としたアプリケーションの設計上のメリットが得られます。パート2ではRestTemplateを使用

して、再利用可能なモデル・オブジェクトを含む軽量のバックエンドや、クライアント側での1行で記述できるWebサービ

スなど、サンプル・アプリケーションの残りの部分を構築します。 </article>

図2

@Configuration@Import(ScreensConfiguration.class)@ImportResource("classpath:applicationContext-security.xml")public class CustomerAppConfiguration { @Bean CustomerModel customerModel() throws IOException { CustomerModel customerModel = new CustomerMod-el(); customerModel.setRestTemplate(restTemplate()); customerModel.loadData(); return customerModel; }

@Bean RestTemplate restTemplate() { RestTemplate restTemplate = new RestTemplate(); restTemplate.setMessageConverters Collections.<HttpMessageConverter<?>>singletonList( new MappingJacksonHttpMessageConverter())); return restTemplate; }}

LISTING 3 LISTING 4 LISTING 5 LISTING 6 LISTING 7

Download all listings in this issue as text

LEARN MORE• Stephen Chinのブログ