Successfully reported this slideshow.
Your SlideShare is downloading. ×

CDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4c

Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Ad
Upcoming SlideShare
Lt agetsuma 拡大するcdi
Lt agetsuma 拡大するcdi
Loading in …3
×

Check these out next

1 of 90 Ad

More Related Content

Slideshows for you (20)

Similar to CDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4c (20)

Advertisement

Recently uploaded (20)

Advertisement

CDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4c

  1. 1. CDI2.0アップデート & クックブック 2016/05/24 上妻 宜人 (あげつま のりと) Java Day Tokyo 2016/Java EE Session 4-C
  2. 2. 上妻 宜人 あげつま のりと •  SIer技術部門でJavaトラブルシューティングの日々 •  Java EEについて調べて伝えることが好き •  コミュニティ講演 •  GlassFish.JP, JJUG CCC, Java Day Tokyo 2015 など
  3. 3. 本日のコンテンツ •  駆け足で振り返るCDI •  CDI2.0 •  CDI + α •  最後に
  4. 4. CDI Context and Dependency Injec0on 2009/12 CDI1.0 - Java EE 6 2013/5 CDI1.1 - Java EE 7 2014/4 CDI1.2 (maintenance release) 2017/1 CDI2.0 - Java EE 8
  5. 5. CDIの目的 1. DI/AOPを中心とした疎結合コードの実現 @Inject, @InterceptorBinding, @Decorator, Event 2. コンテキストを持つオブジェクトのライフサイクル管理 @RequestScoped, @SessionScoped, @Applica0onScoped ... 3. EJB SessionBean と JSF @ManagedBean の統合
  6. 6. CDI 実装製品 •  Weld (参照実装) - jboss.org •  GlassFish, WildFly/JBossEAP, WebLogic •  OpenWebBeans - Apache SoZware Founda0on •  WebSphere, Apache TomEE
  7. 7. Context and Dependency Injec0on: CDI管理Beanの定義 // ライフサイクル: デプロイ〜アンデプロイまで% public class Controller {% % % }% % % // ライフサイクル: ユーザセッションごとに生成、ログアウトで破棄% public class ShoppingCart implements Cart {...}% %
  8. 8. Context and Dependency Injec0on: ランタイム例外を引き起こすコンテキスト操作 public class Controller { % ...% HttpSession session = request.getSession();% session.setAttribute(“shoppingCart”, new ShoppingCart());% % ....% % Cart cart = (Cart)session.getAttribute(“shopingCart”);%
  9. 9. Context and Dependency Injec0on: CDI管理Beanの定義 @ApplicationScoped% public class Controller {% % % }% % % @SessionScoped% public class ShoppingCart implements Cart {...}% %
  10. 10. @ApplicationScoped% public class Controller {% % % }% % % @SessionScoped% public class ShoppingCart implements Cart {...}% % Scope •  @RequestScoped •  @SessionScoped •  @Applica0onScoped •  @Conversa0onScoped •  @Dependent Context and Dependency Injec0on: CDI管理Beanのスコープ
  11. 11. Context and Dependency Injec0on: @Injectでタイプセーフに取得 @ApplicationScoped% public class Controller {% @Inject% Cart cart;% }% % % @SessionScoped% public class ShoppingCart implements Cart {...}% % CDIコンテナがインスタンスをセット
  12. 12. Context and Dependency Injec0on: @InterceptorBinding - タイプセーフなインターセプタ適用 Log target // target% @ApplicationScope% public class OrderService {% public void submit(Order order) {..}% }% // Log% @Interceptor% public class LogInterceptor {...}%
  13. 13. Context and Dependency Injec0on: @InterceptorBinding - タイプセーフなインターセプタ適用 Log target // target% @ApplicationScope% public class OrderService {% public void submit(Order order) {..}% }% // Log% @Interceptor% public class LogInterceptor {...}% @Inherited% @InterceptorBinding% @Target({TYPE, METHOD})% @Retention(RUNTIME)% public @interface Log {}
  14. 14. Context and Dependency Injec0on: @InterceptorBinding - タイプセーフなインターセプタ適用 Log target // target% @ApplicationScope @Log% public class OrderService {% public void submit(Order order) {..}% }% // Log% @Interceptor @Log% public class LogInterceptor {...}% @Inherited% @InterceptorBinding% @Target({TYPE, METHOD})% @Retention(RUNTIME)% public @interface Log {} Binding
  15. 15. CDI1.1の変更点 (Java EE 7) beans.xmlのオプション化 •  beans.xmlなしでCDI有効化 •  スコープを持つクラスはすべてCDI管理Bean @RequestScoped, @SessionScoped, @ApplicationScoped ... •  @Dependentスコープは明示的に付与が必要 // Java EE 7デフォルトでは@Dependent省略不可% @Dependent% public class DependentBean {...}%
  16. 16. CDI1.1の変更点 (Java EE 7) beans.xmlのオプション化 •  @Priority •  主にインターセプタ有効化 & 優先順位付けに使用 •  Interceptorの有効化にbeans.xmlが不要に @Interceptor% @Priority(Interceptor.Priority.APPLICATION)% public class LoggingInterceptor { % @AroundInvoke% public Object log(InvocationContext ic) % throws Exception {...}% }
  17. 17. CDI1.1の変更点 (Java EE 7) @Priorityによるインターセプト順序の定義 @Interceptor @Timeout% @Priority(Interceptor.Priority.APPLICATION + 10)% public class TimeoutInterceptor {...}% Log @Interceptor @Logging% @Priority(Interceptor.Priority.APPLICATION)% public class LogInterceptor {...}% 【値が小さいほど早く起動】% Priority.PLATFORM_BEFORE: 0% @Transactional = 200% Priority.LIBRARY_BEFORE: 1000% Priority.APPLICATION: 2000% アプリケーション向け有効範囲:〜2999% Time out target Priority: 2000 2010
  18. 18. CDI1.1の変更点 (Java EE 7) スコープ開始・終了イベント @ApplicationScoped% public class MasterDataCache {% public void observer(% @Observes @Initialized(ApplicationScoped.class)% ServletContext context) {% // initilize code% }% }% •  スコープの開始・終了タイミングでイベント発火 •  Applica0onScopedの場合@Startup代わりに使える
  19. 19. CDI1.2の変更点 (Java EE 7) JSR-330との互換性確保 •  @javax.inject.Singletonをスキャン対象外へ •  デフォルトでは@SingletonはCDI管理Beanと見なされない •  代わりに @ApplicationScoped を使う •  背景はGuavaを含むAPがCDI1.1からデプロイエラーになったこと Guava 14.0.1 cannot be deployed in a JEE7 Container #1433 https://github.com/google/guava/issues/1433
  20. 20. 本日のコンテンツ •  駆け足で振り返るCDI •  CDI2.0 •  CDI + α •  最後に
  21. 21. CDI2.0 (Java EE 8 / 2017) •  CDI非同期イベント •  仕様をサブセットに分割 •  Java SE Support •  Java SE 8 Alignment
  22. 22. @ApplicationScoped% public class AlertService {% @Inject AlertRepository repo;% % @Transactinal% public void handleAlert(Alert alert) {% // 何らかのビジネスロジックを終えた後に ...% repo.persist(alert);% }% } 通常のメソッド呼び出し 最初はシンプルな機能 Alert Service Alert Repository
  23. 23. @ApplicationScoped% public class AlertService {% @Inject AlertRepository repo;% @Inject EmailSender email;% % @Transactinal% public void handleAlert(Alert alert) {% // 何らかのビジネスロジックを終えた後に ...% repo.persist(alert);% email.send(“test@test.com”, alert);% }% } 通常のメソッド呼び出し アラートが来たらメールも ... Alert Service Alert Repository Email Sender
  24. 24. @ApplicationScoped% public class AlertService {% @Inject AlertRepository repo;% @Inject EmailSender email;% @Inject AlertCache cache;% % @Transactinal% public void handleAlert(Alert alert) {% // 何らかのビジネスロジックを終えた後に ...% repo.persist(alert);% email.send(“test@test.com”, alert);% cache.putIfAbsent(alert);% }% } 通常のメソッド呼び出し アラートが来たらキャッシュ更新も ... Alert Service Alert Repository Email Sender Alert Cache
  25. 25. 通常のメソッド呼び出し 手続き型のデメリット •  機能追加毎にクラス間依存性が増加 •  やがては蜘蛛の巣になる •  CDI管理Beanが持つ状態のロールバックが難しい •  宣言的トランザクションがコミット失敗した場合、 トランザクション中に変更したBeanのステートをどう戻すか •  catch節で頑張れるが、長くなることも
  26. 26. CDIイベントの振り返り イベント発火側のコード Alert Service Alert Repository Email Sender Alert Cache CDI Event @ApplicationScoped% publilc class AlertService {% @Inject AlertRepository repo;% @Inject Event<Alert> event;% % public void handleAlert(Alert alert) {% repo.persist(alert);% event.fire(alert);% ...% %
  27. 27. CDIイベントの振り返り オブザーバの実装 Alert Service Alert Repository Email Sender Alert Cache CDI Event @ApplicationScoped% publilc class AlertService {% @Inject AlertRepository repo;% @Inject Event<Alert> event;% % public void handleAlert(Alert alert) {% repo.persist(alert);% event.fire(alert);% ...% @ApplicationScoped% public class AlertCache {% ...% public void updateCache(@Observes Alert alert) {% cache.putIfAbsent(alert.getId(), alert);% }% }
  28. 28. CDIイベントの振り返り イベントの発火 Alert Service Alert Repository Email Sender Alert Cache CDI Event @ApplicationScoped% publilc class AlertService {% @Inject AlertRepository repo;% @Inject Event<Alert> event;% % public void handleAlert(Alert alert) {% repo.persist(alert);% event.fire(alert);% ...% @ApplicationScoped% public class AlertCache {% ...% public void updateCache(@Observes Alert alert) {% cache.putIfAbsent(alert.getId(), alert);% }% } イベントと同じ引数を持つ 全てのオブザーバに通知
  29. 29. CDIイベントの振り返り イベントモデルの一般的な利点 Alert Service Alert Repository Email Sender Alert Cache CDI Event Alert Service Alert Repository Email Sender Alert Cache •  プラグイン構造 •  既存に手を入れずにObserver追加で拡張 •  実行タイミング/場所の分離 •  非同期実行、別マシンでの実行が理論上は可能となる
  30. 30. CDI Container Subject @Observe Observer #1 @Observe Observer #2 1.fire() 2.call back #1 3.call back #2
  31. 31. CDI Container Subject @Observe Observer #1 @Observe Observer #2 1.fire() thread 2.call back #1 3.call back #2 fire()の完了 CDI1.2までは同期呼び出しのみ
  32. 32. CDI2.0 #1 CDI2.0 非同期イベント
  33. 33. CDI2.0 非同期CDIイベント イベント発火側の実装 @ApplicationScoped% publilc class AlertService {% % @Inject Event<Alert> event;% % public void handleAlert(Alert alert) {% event.fire(alert);% ...% %
  34. 34. CDI2.0 非同期CDIイベント イベント発火側の実装 @ApplicationScoped% publilc class AlertService {% % @Inject Event<Alert> event;% % public void handleAlert(Alert alert) {% event.fireAsync(alert);% ...% %
  35. 35. CDI2.0 非同期CDIイベント イベント発火側の実装 @ApplicationScoped% publilc class AlertService {% % @Inject Event<Alert> event;% % public void handleAlert(Alert alert) {% event.fireAsync(alert);% ...% % CDI2.0 EDR1ではObserver側 スレッドはコンテナ実装依存 Weld 3.0.0.Alpha16の場合: Weld自体が持つスレッドプールを使用 (max-size -> CPUコア数)
  36. 36. CDI2.0 非同期CDIイベント コンテナ管理スレッドの利用 (Concurrency U0li0es for Java EE) @ApplicationScoped% publilc class AlertService {% % @Inject Event<Alert> event;% @Resource ManagedExecutor executor;% % public void handleAlert(Alert alert) {% event.fireAsync(alert, executor);% ...% %
  37. 37. CDI2.0 非同期CDIイベント 全オブザーバの終了待ち受け @ApplicationScoped% publilc class AlertService {% % @Inject Event<Alert> event;% @Resource ManagedExecutor executor;% % public void handleAlert(Alert alert) {% CompletionStage<Alert> asyncEvent = % event.fireAsync(alert, executor);% // block until complete observes% asyncEvent.toCompletableFuture().join(); % ...% %
  38. 38. CDI2.0 非同期CDIイベント Observer側の実装 @ApplicationScoped% publilc class AlertCache {% % ConcurrentMap<Long, Alert> cache = ...;% % public void updateCache(@Observes Alert alert) {% cache.putIfAbsent(alert.getId(), alert);% }% } %
  39. 39. CDI2.0 非同期CDIイベント Observer側の実装 @ApplicationScoped% publilc class AlertCache {% % ConcurrentMap<Long, Alert> cache = ...;% % public void updateCache(@ObserveAsync Alert alert) {% cache.putIfAbsent(alert.getId(), alert);% }% } %
  40. 40. CDI Container Subject @ObserveAsync Observer #1 @ObserveAsync Observer #2 fireAsync() call back call back fireAsync()は即座にreturnし、 各Observerは別スレッドで実行 Request thread Event thread
  41. 41. CDI Container Subject @ObserveAsync Observer #1 @ObserveAsync Observer #2 call back call back transac0on #1 transac0on #2 tx #3 トランザクション・コンテキストは オブザーバに引き継がれない Request thread Event thread call back fireAsync()
  42. 42. CDI2.0 非同期CDIイベント Observerから例外がスローされたらどうなる? @ApplicationScoped% publilc class AlertService {% % @Inject Event<Alert> event;% @Resource ManagedExecutor executor;% % public void handleAlert(Alert alert) {% CompletionStage<Alert> stage = event% .fireAsync(alert, executor);%
  43. 43. CDI2.0 非同期CDIイベント Comple0onStage.excep0onallyによる例外ハンドリング @ApplicationScoped% publilc class AlertService {% % @Inject Event<Alert> event;% @Resource ManagedExecutor executor;% % public void handleAlert(Alert alert) {% CompletionStage<Alert> stage = event% .fireAsync(alert, executor)% .exceptionally(ex -> {% // observer exception logging% Arrays.stream(ex.getSuppressed())% .forEach(e -> System.err.println(e));% return null;% }); %
  44. 44. CDI2.0 非同期CDIイベント CDI2.0より非同期実行に対応 CDI1.2 (Java EE 7) CDI2.0 (Java EE 8) プラグイン (型依存の分離) 非同期実行 (実行タイミングの分離) ○ ○ ○
  45. 45. CDI2.0 非同期CDIイベント @MDBとCDI非同期イベント CDI1.2 (Java EE 7) CDI2.0 (Java EE 8) JMS プラグイン (型依存の分離) 非同期実行 (実行タイミングの分離) メッセージ永続化 Observerの 別マシン実行 ○ ○ ○ ○ ○ ○ ○
  46. 46. CDI1.2 (Java EE 7) CDI2.0 (Java EE 8) JMS プラグイン (型依存の分離) 非同期実行 (実行タイミングの分離) メッセージ永続化 Observerの 別マシン実行 CDI2.0 非同期CDIイベント @MDBとCDI非同期イベント ○ ○ ○ ○ ○ ○ ○ 【JMSに付いてくる検討項目】 XAするならクラッシュリカバリ手順は? ポイズンメッセージ対策は? メッセージ永続化先は?ファイル or DB?
  47. 47. CDI2.0 非同期CDIイベント @MDBとCDI非同期イベント CDI1.2 (Java EE 7) CDI2.0 (Java EE 8) JMS プラグイン (型依存の分離) 非同期実行 (実行タイミングの分離) メッセージ永続化 Observerの 別マシン実行 考えるべき タスクの多さ ○ ○ ○ ○ ○ ○ ○ △
  48. 48. CDI2.0 非同期CDIイベント CDI非同期イベントが適するケース •  順序性, 依存性のない処理の並列実行 •  例外時のCDI管理Bean状態ロールバック •  トランザクション中に変更したステートを元に戻す •  メッセージ永続化が不要 •  例: 朝からリクエスト時点までの業務統計レポート生成 •  障害復旧後に永続メッセージから実行しても、既に陳腐化
  49. 49. CDI2.0 #2 仕様をサブセットに分割
  50. 50. CDI2.0 仕様をサブセットに分割 CDI Lite 軽量なサブセットの抽出 •  CDIを Java EE 以外の世界で使ってもらいたい •  Android, 組込みデバイス •  現状のCDI仕様はJava EE環境を前提 •  プロキシベースを前提としない軽量実装 •  Annota0on Processingによるコンパイル時依存性解決 (Androidでよく使われるDaggerがモデル) •  省メモリ、低CPU使用率の実現
  51. 51. CDI2.0 仕様をサブセットに分割 CDI Lite 軽量なサブセットの抽出 CDI core •  DI - @Inject, Qualifier •  @Produces •  Event & @Observes •  疑似スコープ @Dependent, @Singleton •  Programa0c lookup •  Portable Exten0on CDI Java SE •  Bootstraping API •  Scope in Java SE @Applica0onScoped •  Packaging & deployment CDI Java EE •  Scope in Java EE •  @SessionScoped •  @Conversa0onScoped •  EJBとの連携
  52. 52. CDI2.0 #3 Java SE Support
  53. 53. public static void main(String ... args) {% try (CDI<Object> cdi = CDI.getCDIProvider().initialize()) {% Service service = cdi.select(Service.class).get();% service.doSomething(); % }% }% % public class ServiceImpl implements Service {% @Inject % Repository repo;% % public void doSomething() {...}% }% CDI2.0 Java SE Support Java SE Bootstrap API CDIコンテナ初期化 InjectされたBeanの取得
  54. 54. CDI2.0 Java SE Support “仕様”として含める背景 •  Java EE 仕様間での整合性 •  JAX-RS , JPAは Java SE でも利用可能な仕様設計 •  Weld, OpenWebBeansで既に実装されていた •  実装間で類似APIが複数存在するのはJava EE思想に反する
  55. 55. CDI2.0 #4 Java SE 8 Alignment
  56. 56. CDI2.0 Java SE 8 Alignment InterceptorBuilder: ラムダ or メソッド参照によるインターセプタ public class InterceptorBuilder {% // デプロイ時にCDIコンテナよりコールバック% void afterBeanDiscovery(@Observes AfterBeanDiscovery event) {% event.addInterceptor() // return InterceptorBuilder%
  57. 57. CDI2.0 Java SE 8 Alignment InterceptorBuilder: ラムダ or メソッド参照によるインターセプタ public class InterceptorBuilder {% // デプロイ時にCDIコンテナよりコールバック% void afterBeanDiscovery(@Observes AfterBeanDiscovery event) {% event.addInterceptor()% .intercept(InterceptionType.AROUND_INVOKE, this::log)% % % % % Object log(InvocationContext ic) {% // interceptor impl% }% }% @AroundInvoke相当
  58. 58. CDI2.0 Java SE 8 Alignment InterceptorBuilder: ラムダ or メソッド参照によるインターセプタ public class InterceptorBuilder {% // デプロイ時にCDIコンテナよりコールバック% void afterBeanDiscovery(@Observes AfterBeanDiscovery event) {% event.addInterceptor()% .intercept(InterceptionType.AROUND_INVOKE, this::log)% .priority(Priority.APPLICATION)% .addBinding(Log.INSTANCE);% }% % Object log(InvocationContext ic) {% // interceptor impl% }% }%
  59. 59. CDI2.0 Java SE 8 Alignment InterceptorBuilder: ラムダ or メソッド参照によるインターセプタ public class InterceptorBuilder {% // デプロイ時にCDIコンテナよるコールバック% void afterBeanDiscovery(@Observes AfterBeanDiscovery event) {% event.addInterceptor()% .intercept(InterceptionType.AROUND_INVOKE, this::log)% .priority(Priority.APPLICATION)% .addBinding(Log.INSTANCE);% }% % Object log(InvocationContext ic) {% // interceptor impl% }% }%
  60. 60. CDI2.0 Java SE 8 Alignment InterceptorBuilder: ラムダ or メソッド参照によるインターセプタ event.addInterceptor()% ...% .addBinding(Log.INSTANCE);%
  61. 61. CDI2.0 Java SE 8 Alignment InterceptorBuilder: ラムダ or メソッド参照によるインターセプタ event.addInterceptor()% ...% .addBinding(Log.INSTANCE);% @Log% public void target() {...} 適用対象メソッドと繋ぐために、 アノテーションの“インスタンス”を渡す必要がある
  62. 62. CDI2.0 Java SE 8 Alignment InterceptorBuilder: ラムダ or メソッド参照によるインターセプタ event.addInterceptor()% ...% .addBinding(Log.INSTANCE);% % @Inherited% @InterceptorBinding% @Retention(RUNTIME)% @Target({METHOD, TYPE})% public @interface Log {}%
  63. 63. CDI2.0 Java SE 8 Alignment InterceptorBuilder: ラムダ or メソッド参照によるインターセプタ event.addInterceptor()% ...% .addBinding(Log.INSTANCE);% % @Inherited% @InterceptorBinding% @Retention(RUNTIME)% @Target({METHOD, TYPE})% public @interface Log {% class Literal extends AnnotationLiteral<Log> implements Log {% private Literal() {}% }% final Log INSTANCE = new Literal();% }% CDIのAnnota0onLiteralクラスを継承して アノテーションの”インスタンス”を取得
  64. 64. CDI2.0 Java SE 8 Alignment InterceptorBuilder: ラムダ or メソッド参照によるインターセプタ event.addInterceptor()% ...% .addBinding(Log.INSTANCE);% % @Inherited% @InterceptorBinding% @Retention(RUNTIME)% @Target({METHOD, TYPE})% public @interface Log {% class Literal extends AnnotationLiteral<Log> implements Log {% private Literal() {}% }% final Log INSTANCE = new Literal();% }% @Log% public void target() {...} Interceptor Binding
  65. 65. CDI2.0 Java SE 8 Alignment InterceptorBuilderのメリット •  1クラスで複数のインターセプタ定義が可能 •  クラスが冗長に増えるのを防ぐ •  Java EEの何でもアノテーション状態の改善 •  Java 5 から: アノテーションをスキャンしてコンテナ機能を付与 •  Java 8 から: ラムダを渡すとコンテナが機能付与
  66. 66. CDI2.0 ロードマップ スケジュール •  2015/6: Early DraZ Review 1 •  hkps://docs.jboss.org/cdi/spec/2.0.EDR1/cdi-spec.html •  2016/6: Early DraZ Review 2 予定 •  2016/12 〜 2017/1: CDI2.0 Final 予定 •  2017上半期 Java EE 8 リリース 予定
  67. 67. 本日のコンテンツ •  駆け足で振り返るCDI •  CDI2.0 •  CDI + α •  最後に
  68. 68. DI/AOPが標準化され、非同期イベントが入るのはわかった。 でも、まだ Spring より足りないのでは?
  69. 69. Spring Framework @Autowired, @Aspect% CDI (Java EE) @Inject, @Interceptor DI/AOP プロパティ管理 @Value, @PropertySource% Java起動引数による プロファイル切替 @Profile
  70. 70. CDIは『材料』のみ提供して、 自作が必要なユースケースも多い Spring Framework @Autowired, @Aspect% CDI (Java EE) @Inject, @Interceptor DI/AOP プロパティ管理 @Value, @PropertySource% @Producesによる要自作 Java起動引数による プロファイル切替 @Profile @Alternativeによる要自作
  71. 71. CDI2.0(2017年)に向けて議論中ではある Spring Framework @Autowired, @Aspect% CDI (Java EE) @Inject, @Interceptor DI/AOP プロパティ管理 @Value, @PropertySource% @Producesによる要自作 Java起動引数による プロファイル切替 @Profile CDI-504: have a standard CDI annota0on like @ConfigProperty from deltapsike hkps://issues.jboss.org/browse/CDI-504 CDI-539: Support for 'profile' in CDI hkps://issues.jboss.org/browse/CDI-539 【Issue CDI-504】 @Alternativeによる要自作 【Issue CDI-539】 ・ その機能は本当に『CDI』か? 過去例: @Transac0onalをCDIではなくJTAへ ・ やはり Configra0on JSR では?
  72. 72. CDI2.0(2017年)に向けて議論中ではある CDI (Java EE) @Inject, @Interceptor プロパティ管理 @Value, @PropertySource% @Producesによる要自作 Java起動引数による プロファイル切替 @Profile CDI-504: have a standard CDI annota0on like @ConfigProperty from deltapsike hkps://issues.jboss.org/browse/CDI-504 CDI-539: Support for 'profile' in CDI hkps://issues.jboss.org/browse/CDI-539 【Issue CDI-504】 @Alternativeによる要自作 【Issue CDI-539】 Spring Framework @Autowired, @Aspect%DI/AOP ・ その機能は本当に『CDI』か? 過去例: @Transac0onalをCDIではなくJTAへ ・ やはり Configra0on JSR では? 2017年を待てない場合は Apache Deltaspike
  73. 73. “あったらいいな”はDeltaspikeにある Spring Framework @Autowired, @Aspect% CDI (Java EE) @Inject, @Interceptor DI/AOP プロパティ管理 @Value, @PropertySource% org.apache.deltaspike.core.api.config.% @ConfigProperty Java起動引数による プロファイル切替 @Profile org.apache.deltaspike.core.api.projectstage ProjectStage% Apache Deltaspike
  74. 74. Apache Deltaspike 便利なCDI拡張ライブラリ •  CDIのPortable Exten0onを活かしたライブラリ •  Seem3 + My Faces CODI + α を統合 •  2014/6: 1.0.0 リリース (2016/4 現在 1.6.1が最新)
  75. 75. Apache Deltaspike #1 @ConfigProperty @ConfigPropertyによるパラメータ注入 @ApplicationScoped% public class RemoteConnector {% % @Inject% @ConfigProperty(name="remotehost", defaultValue="localhost:8080")% private String remotehost;% ...% META-INF/apache-deltaspike.proper0es remotehost=192.168.1.2 DeltaspikeによりInject デフォルトのプロパティファイル
  76. 76. Apache Deltaspike #1 @ConfigProperty 任意のプロパティファイルの適用 @Dependent% public class MyAppFileConfig implements PropertyFileConfig {% @Override% public String getPropertyFileName() {% return "META-INF/application.properties";% }% % @Override% public boolean isOptional() {% return false;% }% }
  77. 77. Apache Deltaspike #1 @ConfigProperty 環境変数による値の差し替え @Inject% @ConfigProperty(name="remotehost”,defaultValue="localhost:8080")% private String remotehost;% 【優先順位】 1.  環境変数 export remotehost=192.168.1.2 2.  システムプロパティ java -Dremotehost=192.168.1.4 3.  JNDI new InitialContext().bind(“remotehost”, “192.168.1.5”) 4.  プロパティファイル
  78. 78. Apache Deltaspike #2 ProjectStage 起動オプションで有効なBeanを切り替える Service Repository 【development】 H2 【produc0on】 PostgreSQL META-INF/persistence.xml% <?xml version="1.0" encoding="UTF-8"?>% <persistence>% <persistence-unit name="h2”>...</persistence-unit>% <persistence-unit name="PostgreSQL”>...</persistence-unit>% </persistence>
  79. 79. Apache Deltaspike #2 ProjectStage 起動オプションで有効なBeanを切り替える @ApplicationScoped% public class Repository {% @PersistenceContext(unitName = “h2 or PostgreSQL??”)% private EntityManager em;% ...% }
  80. 80. Apache Deltaspike #2 ProjectStage Development環境向けEn0tyManagerのBean定義 @ApplicationScoped% public class Repository {% @PersistenceContext(unitName = “h2 or PostgreSQL??”)% private EntityManager em;% ...% } @Exclude(exceptIfProjectStage = ProjectStage.Development.class)% @ApplicationScoped% public class DevEntityManagerProducer {% @Produces% @PersistenceContext(unitName = "h2")% private EntityManager em; % }
  81. 81. Apache Deltaspike #2 ProjectStage Development環境向けEn0tyManagerのBean定義 @ApplicationScoped% public class Repository {% @Inject% private EntityManager em;% ...% } @Exclude(exceptIfProjectStage = ProjectStage.Development.class)% @ApplicationScoped% public class DevEntityManagerProducer {% @Produces% @PersistenceContext(unitName = "h2")% private EntityManager em; % }
  82. 82. Apache Deltaspike #2 ProjectStage システムプロパティで有効プロファイルを指定 @ApplicationScoped% public class Repository {% @Inject% private EntityManager em;% ...% } @Exclude(exceptIfProjectStage = ProjectStage.Development.class)% @ApplicationScoped% public class DevEntityManagerProducer {% @Produces% @PersistenceContext(unitName = "h2")% private EntityManager em; % } java -Dorg.apache.deltaspike.ProjectStage=Development Repository H2 PostgreSQL
  83. 83. Apache Deltaspike #2 ProjectStage Produc0on向けも同様 @ApplicationScoped% public class Repository {% @Inject% private EntityManager em;% ...% } @Exclude(exceptIfProjectStage = ProjectStage.Production.class)% @ApplicationScoped% public class ProdEntityManagerProducer {% @Produces% @PersistenceContext(unitName = ”PostgreSQL")% private EntityManager em; % } Repository H2 PostgreSQL
  84. 84. Apache Deltaspike #2 ProjectStage Produc0on向けも同様 @ApplicationScoped% public class Repository {% @Inject% private EntityManager em;% ...% } @Exclude(exceptIfProjectStage = ProjectStage.Production.class)% @ApplicationScoped% public class ProdEntityManagerProducer {% @Produces% @PersistenceContext(unitName = ”PostgreSQL")% private EntityManager em; % } Repository H2 PostgreSQL java -Dorg.apache.deltaspike.ProjectStage=Produc0on
  85. 85. Apache Deltaspike @ConfigPropertyとProjectStage •  2つに共通するメリット •  環境変数やJavaシステムプロパティで振る舞いを変更 •  テスト済warを『修正なし』で複数環境で動作させる 開発環境 ステージング環境 商用環境 AP Server DB myapp.war Simurator myapp.war myapp.war 関連システム
  86. 86. 本日のコンテンツ •  駆け足で振り返るCDI •  CDI2.0 •  CDI + α •  最後に
  87. 87. CDI2.0 (Java EE 8 / 2017) •  CDI非同期イベント •  仕様をサブセットに分割 •  Java SE Support •  Java SE 8 Alignment
  88. 88. CDI2.0をもっと知るには cdi-spec.org / JIRA / Weld3.0.0.Alpha •  ホームページ (CDI spec で検索) •  hkp://www.cdi-spec.org •  JIRA •  hkps://issues.jboss.org/projects/CDI •  CDI2.0 EarlyDraZReview 1 の参照実装 •  Weld 3.0.0.Alpha16 hkp://weld.cdi-spec.org/news/2016/04/28/weld-300Alpha16/ •  WildFly10に組込み可能なpatchもリリース
  89. 89. 最後に CDI2.0 ドラフト仕様は今すぐWildFly10で動きます ぜひ触ってみてください! OracleとJavaは、Oracle Corpora0on及びその子会社、関連会社の米国及びその他の国における登録商標です。 文中の社名、商品名等は各社の商標または登録商標である場合があります。

×