日本オラクル株式会社 Fusion Middleware 事業統轄本部 Java エバンジェリスト 寺 田佳央 Java Day Tokyo 2015 2015 年年 4 月 8 日
以下の事項は 弊社の 一般的な製品の 方向性に関する概要を説明するものです また 情報提供を唯 一の 目的とするものであり いかなる契約にも組み込むことはできません 以下の事項は マテリアルやコード 機能を提供することをコミットメント ( 確約 ) するものではないため 購買決定を 行行う際の判断材料料になさらないで下さい オラクル製品に関して記載されている機能の開発 リリースおよび時期については 弊社の裁量量により決定されます Oracle と Java は Oracle Corpora@on 及びその 子会社 関連会社の 米国及びその他の国における登録商標です 文中の社名 商品名等は各社の商標または登録商標である場合があります Oracle Confiden@al 4
5
6
JPE 1.0 J2EE 1.2 J2EE 1.3 J2EE 1.4 Java EE 5 Java EE 6 Java EE 7 2006 年 5 月 2009 年 12 月 2013 年 5 月
エッセンシャル レシピ 問題 問題 (何がしたいか 解決 (解決方法) 解説 (具体的な説明) Copyright 2015, Oracle and/or its affiliates. All rights reserved. 8
9
WebSocket 1.0 JAX- RS 2.0 JSF 2.2 JSP 2.3 /JSTL JSON- P 1.0 EL 3.0 Servlet 3.1 DI 1.0 / CDI 1.1 / EJB 3.2 JTA 1.2 JCA 1.7 JPA 2.1 JMS 2.0 Batch 1.0 JavaMail 1.5 Bean ValidaOon 1.1 Managed Bean 1.0 Common AnnotaOon 1.2 Interceptors 1.2 Concurrency UOl for EE 1.0 10
11
今日お話をする所 ロジック実装部 ビュー関連処理 ビジネス ロジック データ アクセス DB ロジック Queue 疎結合での実装が重要 Copyright 2015, Oracle and/or its affiliates. All rights reserved. 12
13
14
15
Resource Resources PostConstruct PreDestroy RunAs DeclareRoles RolesAllowed PermitAll DenyAll ManagedBean DataSourceDefiniOon DataSourceDefiniOons Priority 16
JSF Managed Bean CDI EJB JSR- 316 Managed Bean 17
18
Managed Bean 問題 #1 : リソース参照 リソースを参照したい データ ベース JMS (Queue, Topic) トランザクション ORB メール セッション コンテキスト Copyright 2015, Oracle and/or its affiliates. All rights reserved. 19
Ini@alContext ic = new Ini@alContext(); ManagedExecutorService managedexecsvc = (ManagedExecutorService ) ic.lookup (" java:comp/defaultmanagedexecutorservice"); mangedexecsvc.submit(() - > System.out.println( New Thread )); 20
21
@Resource(name = concurrent/defaultmanagedexecutorservice") ManagedExecutorService mangedexecsvc; public void foo(){ mangedexecsvc.submit(() - > System.out.println( New Thread )); 22
23
javax.annota@on @Resource 24
Managed Bean 問題 #2 ライフサイクル管理 インスタンス生成後 インスタンス破棄前 Copyright 2015, Oracle and/or its affiliates. All rights reserved. 25
public class Foo() { @Resource(name = concurrent/defaultmanagedexecutorservice") ManagedExecutorService mangedexecsvc; public Foo(){ mangedexecsvc.submit(() - > System.out.println( Init something )); java.lang.nullpointerexcepoon 26
27
public class Foo() { @Resource(name = concurrent/defaultmanagedexecutorservice") ManagedExecutorService mangedexecsvc; @PostConstruct public void init (){ mangedexecsvc.submit(() - > System.out.println( Init something )); 28
29
javax.annota@on @PostConstruct @PreDestroy 30
: @Resource : @PostConstruct : @PreDestroy 31
32
33
34
Java EE 5 (EJB 3.0) @AroundInvoke @Intercerptors @ExcludeDefaultInterceptors @ExcludeClassInterceptors Java EE 6 (EJB 3.1) ß @InterceptorBinding @Interceptor @AroundTimeout Java EE 7 (EJB 3.1 : Maintenance Release) Interceptor.Priority @AroundConstruct 35
Interceptor 問題 #3 横断的関心事分離 横断的な関心事を分離したい ログ出力 プロファイル 監査 セキュリティ チェック Copyright 2015, Oracle and/or its affiliates. All rights reserved. 36
public void executesomemethod1 () { long start = System.currentTimeMillis(); // ビジネス ロジックの実装 long end = System.currentTimeMillis(); long Ome = end - start; logger.log(level.debug, + Ome); 37
38
public class SomeLogic { @MySimpleProfilerInterceptor public void executesomemethod1 () { 39
40
41
@Inherited @InterceptorBinding @Target({ElementType.TYPE, ElementType.METHOD) @Reten@on(Reten@onPolicy.RUNTIME) public @interface MySimpleProfilerInterceptor { 42
@Priority(Interceptor.Priority.APPLICATION + 10) @MySimpleProfilerInterceptor @Interceptor public class MyInterceptor { @AroundInvoke public Object calcexectime (InvocaOonContext ic) throws Excep@on { // この部分に実装コードを記述 43
@AroundInvoke public Object calcexectime (InvocaOonContext ic) throws ExcepOon { long start = System.currentTimeMillis(); try { return ic.proceed(); // オリジナルの呼び出し catch (Excep@on e) { throw e; finally { long end = System.currentTimeMillis(); long Ome = end - start ; String classname = ic.gettarget().getclass().getsuperclass().getname(); String methodname = ic.getmethod().getname() ; logger.log(level.info, "{0#{1 took {2 (ms)", new Object[]{ classname, methodname, Ome ); 44
@MySimpleProfilerInterceptor public void executesomemethod() { // do Something 情報 : jp.co.oracle.cdis.homepage#executesomemethod took 300 (ms) 45
@MyInteceptor @MyInteceptor @MyInteceptor @MyInteceptor @MyIntecepto 46
47
48
実装レイヤー毎にデータ検証の実装が必要 ビュー関連処理 ビジネス ロジック データ アクセス DB 検証 ロジック Queue 検証 検証 Copyright 2015, Oracle and/or its affiliates. All rights reserved. 49
Bean Validation 問題 #4: 値の検証 宣言的な値の検証 Copyright 2015, Oracle and/or its affiliates. All rights reserved. 50
public class Person { private String name; private String jpzipcode; public String dosomething() { if (name == null name.equals("")) { validaoonfailed();; if (jpzipcode == null jpzipcode.equals("")) { validaoonfailed();; Pajern pajern = Pajern.compile("^\\d{3- \\d{4$"); Matcher matcher = pajern.matcher(jpzipcode); if (!matcher.find()){validaoonfailed(); 51
public class Person { private String name; private String jpzipcode; public String dosomething() { if (name == null name.equals("")) { validaoonfailed();; if (jpzipcode == null jpzipcode.equals("")) { validaoonfailed();; Pajern pajern = Pajern.compile("^\\d{3- \\d{4$"); Matcher matcher = pajern.matcher(jpzipcode); if (!matcher.find()){validaoonfailed(); 52
53
public class Person { @NotNull @Size(min=1) private String name; @NotNull @Size(min=8,max=8) @Pajern("^\\d{3- \\d{4$") private String jpzipcode; public String dosomething() { 54
55
56
依存するクラスのインスタンス生成は? ビジネス ロジック ビュー関連処理 データ アクセス DB ロジック new? Queue Factory? Copyright 2015, Oracle and/or its affiliates. All rights reserved. 57
javax.inject @Inject @Qualifier @Named @Scope @Singleton 58
Dependency Injection 問題 #5 依存性注入 実装を疎結合で実装 型安全 Copyright 2015, Oracle and/or its affiliates. All rights reserved. 59
public class PersonDAOFromCSV implements PersonDAO { public List<Person> getpersons() throws IOExcepOon{ FileSystem fs = FileSystems.getDefault(); Path file = fs.getpath("/tmp/listperson.csv"); return Files.newBufferedReader(file).lines().map(str - > { String[] array = str.split(","); Person person = new Person(); person.setname(array[0]); person.setage(integer.parseint(array[1])); return person; ).collect(collectors.tolist()); 60
public class PersonController { public void listpersonname() throws IOExcep@on { // ある Person の DAO からデータ取得 PersonDAO persondao = new PersonDAOFromCSV(); List<Person> persons = persondao.getpersons(); persons.foreach(person - > System.out.println(person.getName())); new Factory Abstract Factory Service Locator 61
62
public class PersonController { @Inject PersonDAO persondao ; public void listpersonname() throws IOExcep@on { List<Person> persons = persondao.getpersons(); persons.foreach(person - > System.out.println(person.getName())); new - > Factory - > Abstract Factory - > Service Locator 63
64
PersonController new PersonDAO() PersonDAO PersonController @Inject PersonDAO PersonDAO dao.getpersons() dao.getpersons() 65
Dependency Injection 問題 #6 対象の限定 複数の実装から特定の実装 を選択したい Copyright 2015, Oracle and/or its affiliates. All rights reserved. 66
public interface Service { public void dosomething (); public class DukeService implements Service { @Override public void dosomething () { // 何らかの処理理 System.out.println( Duke Service ); public class DuchessService implements Service { @Override public void dosomething () { // 何らかの処理理 System.out.println( Duchess Service ); 67
public class Foo { @Inject private Service service; OR??? public void execservice(){ service.dosomething(); 68
69
@Inject @DukeQualifier Service service1; public void execmul@pleservice(){ service1.dosomething(); @Inject @DuchessQualifier Service service2; public void execmul@pleservice(){ service2.dosomething(); 70
71
72
@Dependent @Qualifier @Reten@on(Reten@onPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER) public @interface DukeQualifier { 73
@DukeQualifier public class DukeServiceImpl implements Service { @Override public void dosomething() { System.out.println("Duke Service"); 74
@Inject @DukeQualifier Service service1; public void execmul@pleservice(){ service1.dosomething(); 75
76
Dependency Injection 問題 #7 不変オブジェクト イミュータブル(不変な) オブジェクトとしてインス タンスを生成したい Copyright 2015, Oracle and/or its affiliates. All rights reserved. 77
public interface Service { public void dosomething (); @DukeQualifier public class DukeService implements Service{ @Override public void dosomething () { // 何らかの処理理 System.out.println( Duke Service ); @Dependent @Qualifier @Reten@on(Reten@onPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER) public @interface DukeQualifier { 78
79
public class Foo { @Inject @DukeQualifier private final Service service; public void execservice(){ service.dosomething(); 80
81
@Dependent public class Foo { private final Service service; @Inject public Foo(@DukeQualifier Service service) { this.service = service; public void execservice(){ service.dosomething(); 82
83
84
Dependency Injection 問題 #8 文字で対象選択 文字列を指定しインジェク ト先を限定したい Copyright 2015, Oracle and/or its affiliates. All rights reserved. 85
public interface Service { public void dosomething (); @Duke @Printer @Foo @Duchess @IoT @Bar @MyEnterprise @GlassFish @Oracle @Hoge @MySQL 86
87
public interface Service { public void dosomething (); @Named(value= duke ) public class DukeService implements Service{ @Override public void dosomething () { // 何らかの処理理 System.out.println( Duke Service ); 88
public interface Service { public void dosomething (); @Named(value= duke ) public class DukeService implements Service{ @Override public void dosomething () { // 何らかの処理理 System.out.println( Duke Service ); @Inject @Named(value= duke ) Service service1; public void execmul@pleservice(){ service1.dosomething(); 89
90
91
public interface Service { public void dosomething (); @Named(value= duke ) public class DukeService implements Service{ @Override public void dosomething () { // 何らかの処理理 System.out.println( Duke Service ); @Inject @Named(value= duke ) Service service1; public void execmul@pleservice(){ service1.dosomething(); 92
DI ではなく CDI 側の仕様確認 Copyright 2015, Oracle and/or its affiliates. All rights reserved. 93
94
95
96
@Resource @Inject DI/CDI Managed Bean @EJB EJB 97
CDI EJB 16:15-17:05 98
javax.decorator javax.enterprise.context javax.enterprise.event javax.enterprise.inject javax.enterprise.uol 99
100
Contexts&Dependency Injection 問題 #9 CDI の有効化 CDI を利用可能にしたい Copyright 2015, Oracle and/or its affiliates. All rights reserved. 101
102
<?xml version="1.0" encoding="utf- 8"?> <beans xmlns="hup://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="hup://www.w3.org/2001/xmlschema- instance" xsi:schemaloca@on="hup://xmlns.jcp.org/xml/ns/javaee hup://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean- discovery- mode="all"> </beans> It is strongly recommended you use "annotated 103
Java Class Java Class Java Class Java Class Java Class Java Class Java Class Java Class Java Class Java Class Java Class CDI Container 104
105
@NormalScope @ApplicaOonScoped @SessionScoped @ConversaOonScoped @RequestScoped @Dependent @Interceptor @Decorator @Stereotype UnsaOsfied dependencies for type NGClass with qualifiers @Default 106
107
Contextual Reference Proxy CDI Container 108
@Inject SomeManagedBean bean; CDI Container Contextual Reference Proxy 109
javax.enterprise.inject.spi.bean Qualifiers Scope Stereotypes Type AlternaOve 110
Contextual Reference CDI Managed Bean Bean Proxy UserTransacOon Principal Validator ValidatorFactory HjpServletRequest HjpSession ServletContext CDI Container 111
Contexts&Dependency Injection 問題 #10 有効範囲の設定 スコープについて Copyright 2015, Oracle and/or its affiliates. All rights reserved. 112
113
15:10-16:00 114
javax.inject.singleton? javax.enterprise.context.applicaoonscoped? 115
@javax.inject.singleton public class DukeCounter { private int counter; public int getcounter() { return counter++; @Singleton Managed Bean 116
117
@javax.enterprise.context.applicaoonscoped public class DukeCounter implements Serializable { private int counter; public int getcounter() { return counter++; 118
119
Contextual Reference CDI Container 120
@SessionScoped // @ConversaOonScoped public class CounterHoldInSession implements Serializable{ @Inject DukeCounter singleton; 121
Contexts&Dependency Injection 問題 #11 : 唯一の選択 ロジックのバージョニング 実装の切替えを行いたい 配備時に切替え プログラミング時に切替え Copyright 2015, Oracle and/or its affiliates. All rights reserved. 122
public interface Service { public void dosomething (); public class DukeSvc implements Service { @Override public void dosomething () { // 何らかの処理理 System.out.println( Duke Service ); DukeAlpha DukeBeta DukeProd 123
public interface DataAccessService { public List<Persion> getdata (); class implements DataAccessService { @Override public List<Person> getdata () { // テスト DB からデータ取得 class implements DataAccessService { @Override public List<Person> getdata () { // 本番 DB からの実データ取得 124
125
126
@Dependend @AlternaOve public class DukeAlpha implements Service{ @Dependend @AlternaOve public class DukeBeta implements Service{ 127
128
@Dependend @AlternaOve public class DukeAlpha implements Service{ @Dependend @AlternaOve public class DukeBeta implements Service{ 129
@Dependend @AlternaOve public class DukeAlpha implements Service{ <beans> <alterna@ves> <class>dukebeta</class> </alterna@ves> </beans> @Dependend @AlternaOve public class DukeBeta implements Service{ 130
@Dependend @AlternaOve @Priority(Interceptor. Priority.APPLICATION + 10) public class DukeAlpha implements Service{ @Dependend @AlternaOve @Priority(Interceptor. Priority.APPLICATION + 20) public class DukeBeta implements Service{ 131
@Inject Service service ; @Dependend @AlternaOve @Priority(Interceptor. Priority.APPLICATION + 20) public class DukeBeta implements Service{ 132
133
@Inject Service @DukeServiceQualifier service ; @DukeServiceQualifier public class DukeServiceWithQualifier implements Service { @AlternaOve 134
@Inject Service @DukeServiceQualifier service ; @DukeServiceQualifier @Specializes public class SpecializedDuke extends DukeServiceWithQualifier { @Override public void dosomething() { 135
Contexts&Dependency Injection 問題 #12 柔軟な生産 CDI Managed Bean でない クラスもインジェクトした い 実行時に対象オブジェクト を変更したい Copyright 2015, Oracle and/or its affiliates. All rights reserved. 136
137
@Stateless public class SomeLogic1 { PersitenceContext (unitname= ORACLE_PU ) EnOtyManager em; @Override public void dosomething () { // 何らかの処理理 System.out.println( Duke Service ); EJB @Stateless public class SomeLogic2 { PersitenceContext (unitname= MYSQL_PU ) EnOtyManager em; @Override public void dosomething () { // 何らかの処理理 System.out.println( Duke Service ); EJB 138
139
140
@Inject @DatabaseQualifier(value= DatabaseList.Oracle) EnOtyManager em; @Inject @DatabaseQualifier(value= DatabaseList.MySQL) EnOtyManager em; 141
142
143
public enum DatabaseList { Oracle, MySQL, PostgreSQL 144
@Dependent @Qualifier @Reten@on(Reten@onPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER) public @interface DatabaseQualifier { DatabaseList value() default DatabaseList.Oracle ; 145
@Dependent public class DatabaseProducer { @Produces @DatabaseQualifier(value = DatabaseList.Oracle) @PersistenceContext(unitName = "ORACLE_PU") private En@tyManager emoracle ; @Produces @DatabaseQualifier(value = DatabaseList.MySQL) @PersistenceContext(unitName = "MySQL_PU") private En@tyManager emmysql; 146
@Dependent @TransacOonal public class SomeBusinessLogic { @Inject @DatabaseQualifier(value= DatabaseList.MySQL) EnOtyManager em; value public List<Person> getpersons(){ em.createquery(..); Oracle 147
Contexts&Dependency Injection 問題 #14 : アノテーションの整理 大規模開発むけ 毎回大量のアノテーション を付加するのは面倒 複数のアノテーションをま とめたい Copyright 2015, Oracle and/or its affiliates. All rights reserved. 148
@Named @RequestScope @SecurityChekIntercepter @LoggerIntercepter @TransacOonal public class IndexPage { @Override public void dosomething () { // 何らかの処理理 System.out.println( Duke Service ); @Named @RequestScope @SecurityChekInterce pter @LoggerIntercepter @TransacOonal public class UserRegPage { @Named @RequestScope @SecurityChekInter cepter @LoggerIntercepter @TransacOonal public class UserConfirmPage { @Named @RequestScope @SecurityChekInter cepter @LoggerIntercepter @TransacOonal public class UserComplPage { 149
150
@MyReqestedScopeStereotype public class IndexPage { @Override public void dosomething () { // 何らかの処理理 System.out.println( Duke Service ); @MyRequestedScope Stereotype public class UserRegPage { @MyRequestedScop estereotype public class UserConfirmPage { @MyRequestedScop estereotype public class UserComplPage { 151
152
@Named @RequestScope @SecurityChekIntercepter @LoggerIntercepter @TransacOonal @Stereotype @Target(TYPE) @Reten@on(RUNTIME) public @interface MyReqestedScopeStereotype { 153
@Named @RequestScope @SecurityChekIntercepter @LoggerIntercepter @TransacOonal public class IndexPage { @Override public void dosomething () { // 何らかの処理理 System.out.println( Duke Service ); @MyReqestedScopeStereotype public class IndexPage { @Override public void dosomething () { // 何らかの処理理 System.out.println( Duke Service ); 154
@Named @ReauestScope public class IndexPage { @Override public void dosomething () { // 何らかの処理理 System.out.println( Duke Service ); @javax.enterprise.inject.model public class IndexPage { @Override public void dosomething () { // 何らかの処理理 System.out.println( Duke Service ); 155
156
Contexts&Dependency Injection 問題 #13 : イベント処理 Observer パターンの適用 イベント処理を行いたい Copyright 2015, Oracle and/or its affiliates. All rights reserved. 157
158
@RequestScoped @Named(value = userreg") public class UserRegistra@onPage { @Inject Event<Mail> mailevent; public void execuserregistra@on() { // ユーザ登録処理理が完了了 mailevent.fire(new Mail(mailaddredd, name, message)); 159
@Applica@onScoped public class MailEventHandler { @Resource(name = "mail/mymailsession") Session mailsession; public void receiveevent(@observes Mail mailevent) { sendmessage(mailevent); 160
161
@Applica@onScoped public class MailEventHandler { @Resource(name = "mail/mymailsession") Session mailsession; public void receiveevent(@observes Mail mailevent) { sendmessage(mailevent); 162
163
@Stateless public class MailEventDispatcherBean { @Inject Event<Mail> mailevent; @Asynchronous public void produceevent(final Mail message) { // ユーザ登録処理理が完了了 mailevent.fire(message); 164
@javax.ejb.singleton public class EventConsumer { @Asynchronous @Lock(LockType.READ) public void consumeevent(@observes Mail message) throws InterruptedExcep@on { // 何か重い処理理 165
@RequestScoped @Named(value = userreg") public class UserRegistra@onPage { @EJB MailEventDispatcherBean dispather; public void execuserregistra@on() { // ユーザ登録処理理が完了了 dispather.produceevent(new Mail(mailaddredd, name, message)); 166
167
168
169
170
171
172