• 検索結果がありません。

[4-C] CDI2.0アップデート&クックブック

N/A
N/A
Protected

Academic year: 2021

シェア "[4-C] CDI2.0アップデート&クックブック"

Copied!
90
0
0

読み込み中.... (全文を見る)

全文

(1)

CDI2.0

アップデート

&

クックブック

NTT

コムウェア株式会社

上妻 宜人

(

あげつま のりと

)

Copyright © NTT COMWARE 2016

(2)

上妻

宜人

あげつま のりと

SIer技術部門でJavaトラブルシューティングの日々

Java EEについて調べて伝えることが好き

コミュニティ講演

(3)

本日のコンテンツ

駆け足で振り返るCDI

CDI2.0

CDI + α

最後に

(4)

CDI

C

ontext and

D

ependency

I

njecAon

2009/12 CDI1.0 - Java EE 6

2013/5 CDI1.1 - Java EE 7

2014/4 CDI1.2

(maintenance release)

(5)

CDI

の目的

1. DI/AOPを中心とした疎結合コードの実現

@Inject, @InterceptorBinding, @Decorator, Event

2. コンテキストを持つオブジェクトのライフサイクル管理

@RequestScoped, @SessionScoped, @ApplicaAonScoped ...

3. EJB SessionBean と JSF @ManagedBean の統合

(6)

CDI

実装製品

Weld

(参照実装) - jboss.org

GlassFish, WildFly/JBossEAP, WebLogic

OpenWebBeans

- Apache So]ware FoundaAon

(7)

Context

and Dependency InjecAon

:

CDI管理Beanの定義

//

ライフサイクル

:

デプロイ

アンデプロイまで

%

public class

Controller

{%

%

%

}%

%

%

//

ライフサイクル

:

ユーザセッションごとに生成、ログアウトで破棄

%

public class

ShoppingCart

implements

Cart {...}%

(8)

Context

and Dependency InjecAon

:

ランタイム例外を引き起こすコンテキスト操作

public class

Controller { %

...%

HttpSession session = request.getSession();%

session.setAttribute(

“sho

pp

ingCart

,

new

ShoppingCart());%

%

....%

%

(9)
(10)

Context

and Dependency InjecAon

:

CDI管理Beanの定義

@ApplicationScoped%

public class

Controller

{%

%

%

}%

%

%

@SessionScoped%

public class

ShoppingCart

implements

Cart {...}%

(11)

@ApplicationScoped%

public class

Controller

{%

%

%

}%

%

%

@SessionScoped%

public class

ShoppingCart

implements

Cart {...}%

%

Scope

@RequestScoped

@SessionScoped

@ApplicaAonScoped

@ConversaAonScoped

@Dependent

Context

and Dependency InjecAon

:

CDI管理Beanのスコープ

(12)

Context and

Dependency InjecAon

:

@Injectでタイプセーフに取得

@ApplicationScoped%

public class

Controller

{%

@Inject%

Cart cart;%

}%

%

%

@SessionScoped%

public class

ShoppingCart

implements

Cart {...}%

%

(13)

Context and

Dependency InjecAon

:

@InterceptorBinding

- タイプセーフなインターセプタ適用

Log target

// target%

@ApplicationScope%

public class OrderService {%

public void submit(Order order) {..}% }%

// Log%

@Interceptor%

(14)

Context and

Dependency InjecAon

:

@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

)%

(15)

Context and

Dependency InjecAon

:

@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

{}

(16)

CDI1.1の変更点

(Java EE 7)

beans.xmlのオプション化

beans.xmlなしでCDI有効化

スコープを持つクラスはすべてCDI管理Bean

@RequestScoped, @SessionScoped, @ApplicationScoped ...

@Dependentスコープは明示的に付与が必要

// Java EE 7

デフォルトでは

@Dependent

省略不可

%

@Dependent%

(17)

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 {...}%

}

(18)

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

(19)

CDI1.1の変更点

(Java EE 7)

スコープ開始・終了イベント

@ApplicationScoped%

public class

MasterDataCache

{%

public

void

observer

(%

@Observes

@Initialized(ApplicationScoped.class)%

ServletContext context) {%

// initilize code%

}%

}

%

スコープの開始・終了タイミングでイベント発火

ApplicaAonScopedの場合@Startup代わりに使える

(20)

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

(21)

本日のコンテンツ

駆け足で振り返るCDI

CDI2.0

CDI + α

最後に

(22)

CDI2.0

(Java EE 8 / 2017)

CDI非同期イベント

仕様をサブセットに分割

Java SE Support

(23)

@ApplicationScoped%

public class

AlertService

{%

@Inject AlertRepository repo;%

%

@Transactinal%

public void

handleAlert

(Alert alert) {%

//

何らかのビジネスロジックを終えた後に

...%

repo.persist(alert);%

}%

}

通常のメソッド呼び出し

最初はシンプルな機能

Alert

(24)

@ApplicationScoped%

public class

AlertService

{%

@Inject AlertRepository repo;%

@Inject EmailSender email;%

%

@Transactinal%

public void

handleAlert

(Alert alert) {%

//

何らかのビジネスロジックを終えた後に

...%

repo.persist(alert);%

email.send(

[email protected]

, alert);%

}%

}

通常のメソッド呼び出し

アラートが来たらメールも

...

Alert

Service Repository Alert Email Sender

(25)

@ApplicationScoped%

public class

AlertService

{%

@Inject AlertRepository repo;%

@Inject EmailSender email;%

@Inject AlertCache cache;%

%

@Transactinal%

public void

handleAlert

(Alert alert) {%

//

何らかのビジネスロジックを終えた後に

...%

repo.persist(alert);%

email.send(

[email protected]

, alert);%

cache.putIfAbsent(alert);%

}%

}

通常のメソッド呼び出し

アラートが来たらキャッシュ更新も

...

Alert

Service Repository Alert Email Sender

Alert Cache

(26)

通常のメソッド呼び出し

手続き型のデメリット

機能追加毎にクラス間依存性が増加

やがては蜘蛛の巣になる

CDI管理Beanが持つ状態のロールバックが難しい

宣言的トランザクションがコミット失敗した場合

トランザクション中に変更した

Beanのステートをどう戻すか

catch節で頑張れるが

長くなることも

(27)

CDIイベントの振り返り

イベント発火側のコード

Alert

Service Repository Alert 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);%

...% %

(28)

CDIイベントの振り返り

オブザーバの実装

Alert

Service Repository Alert 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)

CDIイベントの振り返り

イベントの発火

Alert

Service Repository Alert 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);%

}% }

イベントと同じ引数を持つ

(30)

CDIイベントの振り返り

イベントモデルの一般的な利点

Alert

Service Repository Alert Email Sender Alert Cache CDI Event Alert

Service Repository Alert Email Sender Alert Cache

プラグイン構造

既存に手を入れずに

Observer追加で拡張

実行タイミング

/場所の分離

非同期実行

別マシンでの実行が理論上は可能となる

(31)

CDI

Container Subject

@Observe

Observer #1

Observer #2

@Observe

1.fire()

2.call back #1

(32)

CDI

Container Subject

@Observe

Observer #1

Observer #2

@Observe

1.fire()

thread

2.call back #1 3.call back #2

fire()の完了

CDI1.2までは同期呼び出しのみ

(33)

CDI2.0 #1

(34)

CDI2.0 非同期CDIイベント

イベント発火側の実装

@ApplicationScoped%

publilc class

AlertService {%

%

@Inject Event<Alert> event;%

%

public void

handleAlert(Alert alert) {%

event.fire(alert);%

...%

(35)

CDI2.0 非同期CDIイベント

イベント発火側の実装

@ApplicationScoped%

publilc class

AlertService {%

%

@Inject Event<Alert> event;%

%

public void

handleAlert(Alert alert) {%

event.

fireAsync

(alert);%

...%

(36)

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コア数)

(37)

CDI2.0 非同期CDIイベント

コンテナ管理スレッドの利用

(Concurrency UAliAes for Java EE)

@ApplicationScoped%

publilc class

AlertService {%

%

@Inject Event<Alert> event;%

@Resource ManagedExecutor

executor

;%

%

public void

handleAlert(Alert alert) {%

event.fireAsync(alert,

executor

);%

...%

(38)

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()

; %

...%

(39)

CDI2.0 非同期CDIイベント

Observer側の実装

@ApplicationScoped%

publilc class

AlertCache {%

%

ConcurrentMap<Long, Alert> cache = ...;%

%

public void

updateCache(@Observes Alert alert) {%

cache.putIfAbsent(alert.getId(), alert);%

}%

}

%

(40)

CDI2.0 非同期CDIイベント

Observer側の実装

@ApplicationScoped%

publilc class

AlertCache {%

%

ConcurrentMap<Long, Alert> cache = ...;%

%

public void

updateCache(

@ObserveAsync

Alert alert) {%

cache.putIfAbsent(alert.getId(), alert);%

}%

}

%

(41)

CDI

Container Subject

@ObserveAsync

Observer #1

Observer #2

@ObserveAsync

fireAsync() call back call back

fireAsync()は即座にreturnし

Observerは別スレッドで実行

Request thread

Event thread

(42)

CDI

Container Subject

@ObserveAsync

Observer #1

Observer #2

@ObserveAsync

call back call back transacAon #1 transacAon #2 tx #3

トランザクション・コンテキストは

オブザーバに引き継がれない

Request thread

Event thread

call back fireAsync()

(43)

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);%

(44)

CDI2.0 非同期CDIイベント

CompleAonStage.excepAonallyによる例外ハンドリング

@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;%

(45)

CDI2.0 非同期CDIイベント

CDI2.0より非同期実行に対応

CDI1.2

(Java EE 7) (Java EE 8)

CDI2.0

プラグイン

(型依存の分離)

非同期実行

(実行タイミングの分離)

(46)

CDI2.0 非同期CDIイベント

@MDBとCDI非同期イベント

CDI1.2

(Java EE 7) (Java EE 8)

CDI2.0

JMS

プラグイン

(型依存の分離)

非同期実行

(実行タイミングの分離)

メッセージ永続化

Observerの

別マシン実行

(47)

CDI1.2

(Java EE 7) (Java EE 8)

CDI2.0

JMS

プラグイン

(型依存の分離)

非同期実行

(実行タイミングの分離)

メッセージ永続化

Observerの

別マシン実行

CDI2.0 非同期CDIイベント

@MDBとCDI非同期イベント

JMS

付いてくる検討項目】

XAするならクラッシュリカバリ手順は?

ポイズンメッセージ対策は?

メッセージ永続化先は?ファイル

or

DB?

(48)

CDI2.0 非同期CDIイベント

@MDBとCDI非同期イベント

CDI1.2

(Java EE 7) (Java EE 8)

CDI2.0

JMS

プラグイン

(型依存の分離)

非同期実行

(実行タイミングの分離)

メッセージ永続化

Observerの

別マシン実行

考えるべき

タスクの多さ

(49)

CDI2.0 非同期CDIイベント

CDI非同期イベントが適するケース

順序性

, 依存性のない処理の並列実行

例外時の

CDI管理Bean状態ロールバック

トランザクション中に変更したステートを元に戻す

メッセージ永続化が不要

: 朝からリクエスト時点までの業務統計レポート生成

障害復旧後に永続メッセージから実行しても

既に陳腐化

(50)

CDI2.0 #2

(51)

CDI2.0 仕様をサブセットに分割

CDI Lite 軽量なサブセットの抽出

CDIを Java EE 以外の世界で使ってもらいたい

Android, 組込みデバイス

現状の

CDI仕様はJava EE環境を前提

プロキシベースを前提としない軽量実装

AnnotaAon Processingによるコンパイル時依存性解決

(Androidでよく使われるDaggerがモデル)

省メモリ

CPU使用率の実現

(52)

CDI2.0 仕様をサブセットに分割

CDI Lite 軽量なサブセットの抽出

CDI core

•  DI - @Inject, Qualifier •  @Produces •  Event & @Observes •  疑似スコープ @Dependent, @Singleton •  ProgramaAc lookup •  Portable ExtenAon

CDI Java SE

•  Bootstraping API •  Scope in Java SE @ApplicaAonScoped •  Packaging & deployment

CDI Java EE

•  Scope in Java EE •  @SessionScoped •  @ConversaAonScoped •  EJBとの連携

(53)

CDI2.0 #3

(54)

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コンテナ初期化

(55)

CDI2.0 Java SE Support

“仕様”として含める背景

Java EE 仕様間での整合性

JAX-RS , JPAは Java SE でも利用可能な仕様設計

Weld, OpenWebBeansで既に実装されていた

実装間で類似

APIが複数存在するのはJava EE思想に反する

(56)

CDI2.0 #4

(57)

CDI2.0 Java SE 8 Alignment

InterceptorBuilder: ラムダ or メソッド参照によるインターセプタ

public class InterceptorBuilder {%

// デプロイ時にCDIコンテナよりコールバック%

void afterBeanDiscovery(@Observes AfterBeanDiscovery event) {%

(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)%

%

%

%

%

Object log(InvocationContext ic) {% // interceptor impl%

}% }%

(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)

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%

}% }%

(61)

CDI2.0 Java SE 8 Alignment

InterceptorBuilder: ラムダ or メソッド参照によるインターセプタ

event.addInterceptor()% ...%

(62)

CDI2.0 Java SE 8 Alignment

InterceptorBuilder: ラムダ or メソッド参照によるインターセプタ

event.addInterceptor()% ...% .addBinding(Log.INSTANCE);%

@Log%

public void

target() {...}

適用対象メソッドと繋ぐために

(63)

CDI2.0 Java SE 8 Alignment

InterceptorBuilder: ラムダ or メソッド参照によるインターセプタ

event.addInterceptor()% ...% .addBinding(Log.INSTANCE);% % @Inherited% @InterceptorBinding% @Retention(RUNTIME)% @Target({METHOD, TYPE})%

(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();% }%

CDIのAnnotaAonLiteralクラスを継承して

(65)

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() {...}

(66)

CDI2.0 Java SE 8 Alignment

InterceptorBuilderのメリット

1クラスで複数のインターセプタ定義が可能

クラスが冗長に増えるのを防ぐ

Java EEの何でもアノテーション状態の改善

Java 5

から

: アノテーションをスキャンしてコンテナ機能を付与

Java

8

から

: ラムダを渡すとコンテナが機能付与

(67)

CDI2.0 ロードマップ

スケジュール

2015/6: Early Dra] Review 1

hmps://docs.jboss.org/cdi/spec/2.0.EDR1/cdi-spec.html

2016/6: Early Dra] Review 2

予定

2016/12

2017/1: CDI2.0 Final

予定

2017上半期 Java EE 8 リリース

予定

(68)

本日のコンテンツ

駆け足で振り返るCDI

CDI2.0

CDI + α

(69)

DI/AOPが標準化され

非同期イベントが入るのはわかった

(70)

Spring Framework

@Autowired

, @Aspect%

CDI

(Java EE)

@Inject

, @Interceptor

DI/AOP

プロパティ管理

@Value,

@PropertySource%

Java起動引数による プロファイル切替

@Profile

(71)

CDIは『材料』のみ提供して、

自作が必要なユースケースも多い

Spring Framework

@Autowired

, @Aspect%

CDI

(Java EE)

@Inject

, @Interceptor

DI/AOP

プロパティ管理

@Value,

@PropertySource%

@Producesによる

要自作

Java起動引数による プロファイル切替

@Profile

@Alternative

による要自作

(72)

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 annotaAon like @ConfigProperty from deltapsike

hmps://issues.jboss.org/browse/CDI-504 CDI-539: Support for 'profile' in CDI hmps://issues.jboss.org/browse/CDI-539

Issue CDI-504】

@Alternative

による要自作

Issue CDI-539】

その機能は本当に

CDI

か?

過去例:

@TransacAonalをCDIではなくJTAへ

やはり

ConfigraAon JSR では?

(73)

CDI2.0

(2017

)

に向けて議論中ではある

CDI

(Java EE)

@Inject

, @Interceptor

プロパティ管理

@Value,

@PropertySource%

@Producesによる

要自作

Java起動引数による プロファイル切替

@Profile

CDI-504: have a standard CDI annotaAon like @ConfigProperty from deltapsike

hmps://issues.jboss.org/browse/CDI-504 CDI-539: Support for 'profile' in CDI hmps://issues.jboss.org/browse/CDI-539

Issue CDI-504】

@Alternative

による要自作

Issue CDI-539】

Spring Framework

@Autowired

, @Aspect%

DI/AOP

その機能は本当に

CDI

か?

過去例:

@TransacAonalをCDIではなくJTAへ

やはり

ConfigraAon JSR では?

2017

年を待てない場合は

Apache Deltaspike

(74)

“あったらいいな”は

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

(75)

Apache Deltaspike

便利な

CDI拡張ライブラリ

CDIのPortable ExtenAonを活かしたライブラリ

Seem3 + My Faces CODI + α を統合

(76)

Apache Deltaspike #1

@ConfigProperty

@ConfigPropertyによるパラメータ注入

@ApplicationScoped%

public class RemoteConnector {% %

@Inject%

@ConfigProperty(name="remotehost", defaultValue="localhost:8080")% private String remotehost;%

...%

META-INF/apache-deltaspike.properAes

remotehost=192.168.1.2

DeltaspikeによりInject

(77)

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;%

}% }

(78)

Apache Deltaspike #1

@ConfigProperty

環境変数による値の差し替え

@Inject%

@ConfigProperty(name="remotehost”,defaultValue="localhost:8080")%

private String remotehost;%

【優先順位】

1.

環境変数

export

remotehost

=192.168.1.2

2.

システムプロパティ

java -D

remotehost

=192.168.1.4

3.

JNDI

new InitialContext().bind(“remotehost”, “192.168.1.5”)

(79)

Apache Deltaspike #2

ProjectStage

起動オプションで有効な

Beanを切り替える

Service

Repository 【development】

H2

【producAon】

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>

(80)

Apache Deltaspike #2

ProjectStage

起動オプションで有効な

Beanを切り替える

@ApplicationScoped%

public class

Repository {%

@PersistenceContext(unitName =

“h2 or PostgreSQL??”

)%

private

EntityManager

em

;%

...%

}

(81)

Apache Deltaspike #2

ProjectStage

Development環境向けEnAtyManagerの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; %

(82)

Apache Deltaspike #2

ProjectStage

Development環境向けEnAtyManagerの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; %

(83)

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

(84)

Apache Deltaspike #2

ProjectStage

ProducAon向けも同様

@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

(85)

Apache Deltaspike #2

ProjectStage

ProducAon向けも同様

@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

(86)

Apache Deltaspike

@ConfigPropertyとProjectStage

2つに共通するメリット

環境変数や

Javaシステムプロパティで振る舞いを変更

テスト済

warを『修正なし』で複数環境で動作させる

開発環境 ステージング環境 商用環境 AP Server DB myapp.war Simurator myapp.war myapp.war 関連システム

(87)

本日のコンテンツ

駆け足で振り返るCDI

CDI2.0

CDI + α

(88)

CDI2.0

(Java EE 8 / 2017)

CDI非同期イベント

仕様をサブセットに分割

Java SE Support

(89)

CDI2.0をもっと知るには

cdi-spec.org / JIRA / Weld3.0.0.Alpha

ホームページ

(CDI spec で検索)

hmp://www.cdi-spec.org

JIRA

hmps://issues.jboss.org/projects/CDI

CDI2.0 EarlyDra]Review 1 の参照実装

Weld 3.0.0.Alpha16

hmp://weld.cdi-spec.org/news/2016/04/28/weld-300Alpha16/

WildFly10に組込み可能なpatchもリリース

(90)

最後に

CDI2.0 ドラフト仕様は今すぐWildFly10で動きます

ぜひ触ってみてください!

OracleとJavaは、Oracle CorporaAon及びその子会社、関連会社の米国及びその他の国における登録商標です。 文中の社名、商品名等は各社の商標または登録商標である場合があります。

参照

関連したドキュメント

注1) 本は再版にあたって新たに写本を参照してはいないが、

あれば、その逸脱に対しては N400 が惹起され、 ELAN や P600 は惹起しないと 考えられる。もし、シカの認可処理に統語的処理と意味的処理の両方が関わっ

前処理フィルタ2B 漏えい個所 漏えいあり 腐⾷あり スラッジ塊あり 異常なし. 

ぼすことになった︒ これらいわゆる新自由主義理論は︑

賠償請求が認められている︒ 強姦罪の改正をめぐる状況について顕著な変化はない︒

行ない難いことを当然予想している制度であり︑

けることには問題はないであろう︒

単に,南北を指す磁石くらいはあったのではないかと思