17. ここでnewしてしまうと効果があまりない
public class ServiceImpl implements Service {
DAO/Repository
…
さらなる
Service
@Override public void doBusiness() 依存先クラス
{
new
インタフェース
dao.select();
REST
call
} Endpoint
実装クラスでDBにアクセス
実装クラス
}
DBMS
ClassA
JAX-‐WS
Client
自分でローカル変数にnewすると
@Path (“/sample”) Service
ユニットテスト時にDBにアクセス
さらなる
call
してしまう。
public class SampleResource { new
依存先クラス
インタフェース
public Entity sampleMethod () { Mail
Client
さらなる
Service service =実装クラス
new
依存先クラス
new ServiceImpl();
service.doBusiness();
…
関連他システム
メールサーバ
22. 再掲 :
各クラスを new
で繋いだ場合
DAO/Repository
Service
REST
Endpoint
new
テスト
対象
ClassA
new
new
さらなる
依存先クラス
依存先
クラス
DBMS
ユニットテストに
JAX-‐WS
Client
Service
依存先
クラス
必要なクラス
new
さらなる
依存先クラス
Mail
Client
new
関連他システム
さらなる
依存先クラス
メールサーバ
43. 静的な型解決
:
Qualifier
(修飾子) の使用
2.
インジェクション先とBean両方に付与する
OracleDAOをインジェクションしたい場合は@Injectと@Oracleを指定
@Inject
@Oracle
private
DAO
dao;
@Oracle
public
class
OracleDAO
…
@PostgreSQL
public
class
PostgresDAO
…
44. 静的な型解決
:
Qualifier
(修飾子) の使用
3.
インジェクション対象を変更したい場合
PostgresDAOをインジェクションしたい場合は修飾子を書き換える。
@Inject
@PostgreSQL
private
DAO
dao;
@Oracle
public
class
OracleDAO
…
@PostgreSQL
public
class
PostgresDAO
…
52. @RequestScoped
:
リクエスト受付~応答まで
クライアント
サーバ
request
response
@RequestScoped
public
class
SampleBean
{
…
}
@Path
(“/sample”)
public
class
SampleResource
{
@Inject
SampleBean
bean;
リクエスト毎にインジェクションしなおす
53. @SessionScoped
:
ログイン~ログアウト
クライアント
サーバ
Login
Logout
@SessionScoped
public
class
User
implements
Serializable
{
…
}
@Model
//
JSF2.x
public
class
SampleController
{
@Inject
User
user;
同一セッション中は、状態が保持された
同じインスタンスがインジェクションされる
54. @ConversaOonScoped
:
Session未満の任意長さ
クライアント
サーバ
Login
Begin
End
Logout
@Named
@ConversaOonScoped
public
class
ConversaOonController
implements
Serializable
{
@Inject
private
ConversaOon
conversaOon;
public
void
begin()
{
…
conversaOon.begin();
}
public
void
end()
{
…
conversaOon.end();
}
56. @Dependent
:
インジェクション先に合わせる (default)
Servlet
call
サーブレットは
シングルインスタンス
<<interface>>
Service
ServiceImpl
@WebServlet(“/sample”)
public
class
SampleServlet
extends
HcpServlet
{
サーブレット生成時に
@Inject
一度だけインジェクション
private
Service
service;
//
デフォルトは @Dependent
であると暗黙的に判定
public
class
ServiceImpl
extends
Service
{…}
70. 3層モデルの依存性をDIで繋ぐ
シンプルに new
で繋いでいくと …
Java EE の 3層アーキテクチャ
Web 層
REST
Endpoint
(JAX-‐RS2.x)
BackingBean
(JSF2.x)
永続化層
ビジネス 層
new
new
Service
(CDI
Bean)
new
Repository
(JPA2.x)
RDBMS
クライアント
WebSocket
Servlet
RDBMS以外の
永続化機構
(KVSなど)
71. 3層モデルの依存性をDIで繋ぐ
冒頭の通り依存性が強くテストできない等 の課題
Java EE の 3層アーキテクチャ
Web 層
REST
Endpoint
(JAX-‐RS2.x)
永続化層
ビジネス 層
new
new
Service
(CDI
Bean)
new
Repository
(JPA2.x)
RDBMS
BackingBean
(JSF2.x)
クライアント
テスト
対象
WebSocket
Servlet
テストに必要
RDBMS以外の
永続化機構
(KVSなど)
72. 3層モデルの依存性をDIで繋ぐ
@Injectでユニットテストしやすく、依存性を少なく。
Java EE の 3層アーキテクチャ
Web 層
クライアント
REST
Endpoint
(JAX-‐RS2.x)
ビジネス 層
永続化層
Service
(CDI
Bean)
Repository
(JPA2.x)
RDBMS
REST処理
@Path(“/sample”)
public
class
Resource
{
@Inject
private
Service
service;
業務処理
DBアクセス
public
class
Service
{
public
class
Repository
{
@Inject
private
Repository
…
@PersistenceContext
private
EnOtyManager
..
インジェクション
インジェクション