Spring Day 2016 springの現在過去未来

44
For Beginner For Beginner Springの 現在,過去,未来 日本Springユーザ会 長谷川 裕一 1

Transcript of Spring Day 2016 springの現在過去未来

For BeginnerFor Beginner

Springの

現在,過去,未来

日本Springユーザ会

長谷川 裕一

1

For Beginner

2

自己紹介• 長谷川 裕一

– 日本Springユーザ会会長、Starlight&Storm 代表

• 1986年、イリノイ州警察指紋システムのアセンブリ言語プログラマからスタート、色々あって、CORBAからEJB、Webサービスを経て

Springへ

• 国内で も初期のXPコンサルタント

• 現在はオブジェクト指向を中心に、コンサルティング(IT戦略、技術、プロセスetc)や教育で活動

• 書籍– プログラムの育てかた(ソフトバンク),Spring入門,Spring2.0入門,

Spring3入門,間違いだらけのソフトウェア・アーキテクチャ(技術評論社)

• その他– SQuBOK策定メンバ, チェンジビジョン・コンサルティング・パートナー

For Beginner

本日のハナシ

• 0. Spring誕生

– 2000~2003年 J2EE(EJB)の全盛期

• 1. Spring乳児期

– 2004~2008年 SpringがDIとAOPだった時代

• 2. Spring幼年期

– 2009〜2016年 Microservice、Cloudへ

3

高齢者の昔話なので期待しないで聞いておくれ。

For Beginner

本日のハナシ

• 0. Spring誕生

– 2000~2003年 J2EE(EJB)の全盛期

• 1. Spring乳児期

– 2004~2008年 SpringがDIとAOPだった時代

• 2. Spring幼年期

– 2009〜2015年 Microservice、Cloudへ

4

入社前の話だ…

For Beginner

Spring登場前後

20032000

J2EE1.2EJB1.1Servlet2.1JSP1.1

Struts

J2EE1.4EJB2.1Servlet2.4JSP2.0

2006

JavaEE5EJB3Servlet2.5JSP2.1

SpringHibernate

Seasar2

Remoteから

LocalなInterface

POJO&

JPA

5

JSUG

EJB1の話でもしようかのぅ

For Beginner

EJB1-分散メカニズム• 2種類のEnterprise Bean(2.0からMDB追加)

– SessionBean

– EntityBean

EJB ContaiterInstance Pooling

: C lient C ode

: Hom e Interface

: EJB O bject

: Enterprise Bean

: Hom e O bject

: Rem ote Interface

1: 新しいEJBO bjectの生成依頼

3: EJBO bjectの参照を返す

4: 処理の依頼

5: 処理をデレゲート

2: EJB O bjectを生成

: Enterprise Bean

assign

6

Remoteアクセスしかなかったんじゃよ。

For Beginner

10年早くて、間違って使われたEJB

• 時代はローカルなWebアプリケーション

– 分散オブジェクトは過剰、ローカルアクセスだけで十分

– 単なるトランザクションスクリプトとORMが欲しい

– SQLは自分で書いた方がいい(CMPは使わない)

– コンテナがないとテストできない

– 再利用(ポータビリティ)の仕組みを考えたけど、再利用できない

•7

ポータビリティを考えたんですか?

そうそうそういう団体がありましたねぇ

EJBは分散を捨てたんじゃ。そしてSpringの真似を始めたのじゃ。そのまま分散で進んでいたら今頃…

For Beginner

2000年頃のWebアプリ

EIS層中間層Client層

RDBBrowserJavaBeans 自家製の

フレームワーク自家製のフレームワーク

プレゼンテーション層 ビジネス層 データアクセス層

Session Bean Entity Bean

8

いわゆる普通の業務アプリじゃよ。

EJBはサッカーチームのメンバに、空きがあるからと入れられた

キックボクサーみたいなもので、

EJBが可哀想じゃったよ…

For Beginner

Spring誕生

• 実践J2EE

– 重厚なJava EE(EJB)の否定

– 軽量なコンテナ Spring0.9

2003

9

なんのポーズですか?

For Beginner

本日のハナシ

• 0. Spring誕生

– 2000~2003年 J2EE(EJB)の全盛期

• 1. Spring乳児期

– 2004~2008年 SpringがDIとAOPだった時代

• 2. Spring幼年期

– 2009〜2015年 All in OneからMicroserviceとCloudへ

10

For Beginner

EJBのInterfaceで目覚めた

• Interfaceってそうやって使うのか!

– Interfaceは部品間をつなぐ

• ソフトウェアを電気製品みたいに部品化したい

– 部品化 = インタフェース接続

•11

それまでは、部品化って考えてなかったんですか?

時代はまだまだ、

モノリシックなアプリケーションが多かったのじゃ。

For Beginner

インタフェースとレイヤ,パッケージ• 変更単位や開発単位に適宜導入する

– レイヤ

• パソコン本体, ディスプレイ, キーボード...

– パッケージ(コンポーネント)

• パソコンの中のCPU, メモリ, HDD...

– 密結合なオブジェクト

• CPUやメモリの中の、ハンダ付けされた部品

•12

プレゼンテーション

ビジネスロジック

データベースアクセス

RDB

ブラウザ

表示の仕組み 永続化の仕組み業務の仕組み

それに、Interfaceを使うにはFactoryなど自分で用意しないといけなかったからのぅ。

For Beginner

Spring – 利用前• Serviceクラス(具象)

– Interfaceを利用するためにFactory Methodが別途必要

– トランザクション管理や例外、ログの処理が必要

•13

public class EmployeeServiceImplimplements EmployeeService{

・・・

public List findAll() throws Exception {if(Log.flag) { System.out.println(“***Start”); }Connection conn = null;・・・

EmployeeDao dao = (EmployeeDao)Factory.create(KEY);

List employeeList = null;try {employeeList = dao.findAll(conn);conn.commit();

} catch(Exception e) {conn.rollback();・・・

} finally {conn.close();・・・

}if(Log.flag) { System.out.println(“***End”); }return employeeList;

}・・・ 今思えば、同じことを何度も

コーディングしておったのぅ。

For Beginner

余談:設計の原則

• 背景

– Interfaceの置かれている場所が、おかしいことが多々有る

• 原則

– Interfaceは偉い方に置く

– Interfaceの置かれている場所で、部品(コンポーネント)間の序列が分からなければいけない

14

電気製品で考えればわかるじゃろ?電気製品から伸びているコードを差し込みに行く

「穴」がInterfaceじゃ。

電気製品は穴が空いている方が、偉いんじゃよ。

For Beginner

Spring 1

• Spring1.0

– DIxAOP コンテナの原点。XML Bean定義ファイル時代の幕開け

• Spring1.1

– XML Bean 定義ファイルの簡略化

• Spring1.2

– さらなるXML Bean 定義ファイルの簡略化

• Other Products

– Spring Web Flow

2004

2005

15

いよいよ登場かな?

For Beginner

Spring - DIコンテナ

• DI(Dependency Injection)

– 依存性の注入

• インタフェースの導入が楽

•16

EmpServiceImpl

DIコンテナ

①生成

②セット(依存性の注入)

③利用EmpDaoImpl

EmpDao

For Beginner

AOPを使ってもっと部品化する

• AOPを使えば処理を後からクラスに追加できる

– 例:トレースログを追加する

•17

public class DaoImpl extends Dao{・・・public List find() {

List list = select();return list;

}}

>java ・・・16:00:01 *Start* find() DaoImpl16:00:02 *End* find() DaoImpl17:02:12 *Start* find() DaoImpl17:02:13 *End* find() DaoImpl

DaoImpl

find()ServiceImpl

find()を呼ぶ

Dao

実行結果

For Beginner

AOPの仕組み例• Proxyベース(かつ、定義ファイル利用)の場合、ProxyオブジェクトはAOP

のコンテナが自動生成する

•18

:Proxy

:Bean

Interface:Client

Bean定義

ファイル

Adviceの呼び出し

自動生成

:Advice

:Spring

Pointcutの参照

処理の依頼

処理の依頼

For Beginner

Spring - AOP• Joinpointはメソッドの開始時、終了時

• Pointcutはワイルドカード風(!?)

• AdviceはAround、Before、After、After Returning、Throw

• 主な利用方法

– トランザクション管理

• トランザクション管理は難しいくプログラマに任せられない

– ログ管理

• メソッドの開始と終了のトレースログが正しく出力されない

– 誰もフォーマットを守らない

– トレースログを追加し忘れる

– 例外管理

• 処理の途中でExceptionが握りつぶされてしまう

– Exceptionを実行時例外にする

•19

For Beginner

Spring – 利用後

public class EmployeeServiceImplimplements EmploeeService {

private EmployeeDao dao;

public List findAll() {return dao.findAll();

}・・・

public void setEmployeeDao(EmployeeDao dao) {this.dao = dao;

}}

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans><!-- jdbc --><bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations">

<list><value>com/mamezou/config/jdbc.properties</value>

</list></property>

</bean><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

<property name="driverClassName"><value>${jdbc.driverClassName}</value></property><property name="url"><value>${jdbc.url}</value></property><property name="username"><value>${jdbc.username}</value></property><property name="password"><value>${jdbc.password}</value></property>

</bean><!-- Hibernate SessionFactory --><bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">

<property name="dataSource"><ref local="dataSource" /></property><property name="mappingResources">

<value>com/mamezou/person/dao/hibernate/person.hbm.xml</value></property><property name="hibernateProperties">

<props><prop key="hibernate.dialect">net.sf.hibernate.dialect.HSQLDialect</prop><prop key="hibernate.c3p0.minPoolSize">1</prop> <prop key="hibernate.c3p0.maxPoolSize">2</prop><prop key="hibernate.show_sql">true</prop>

</props></property>

</bean><!-- Transaction Manager --><bean id="transactionManager"

class="org.springframework.orm.hibernate.HibernateTransactionManager"><property name="sessionFactory"><ref local="sessionFactory" /></property>

</bean>

<!-- Business Interface --><bean id="personService"

class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"><property name="transactionManager"><ref local="transactionManager" /></property><property name="target"><ref local="personServiceTarget" /></property><property name="transactionAttributes">

<props><prop key="find*">PROPAGATION_REQUIRED, readOnly</prop><prop key="add*">PROPAGATION_REQUIRED, -AddPersonException</prop><prop key="remove*">PROPAGATION_REQUIRED, -RemovePersonException</prop>

</props></property>

</bean>

<!-- Business Object --><bean id="personServiceTarget" class="com.mamezou.person.business.PersonServiceImpl">

<property name="personDao"><ref local="personDao"/></property></bean>

<!-- Data Access Object --> <bean id="personDao" class="com.mamezou.person.dao.hibernate.PersonDaoImpl">

<property name="sessionFactory"><ref local="sessionFactory"/></property></bean>

</beans>

コードはすっきり

XML Bean定義(イメージです。拡大しないように)

20

スライド13より格段に減ってる!

For Beginner

Spring 2• Spring2.0

– Bean 定義ファイルが DTD から XML スキーマ形式に変更(独

自スキーマが 使えるようになった)

– アノテーションの登場

– JPA やスクリプト言語のサポートと多機能化へ突入

• Spring2.5

– アノテーションの強化

• @Autowired

• Other Products

– Spring Security、Spring Batch

2006

2007

21

Since2006Springの知名度が

少しずつ上がってきた頃じゃ。

For Beginner

Spring – 利用後

•22

public class EmployeeServiceImpl implements EmploeeService {

@Autowiredprivate EmployeeDao dao;

@Transactionalpublic List findAll() {

return dao.findAll();}

・・・//public void setEmployeeDao(EmployeeDao dao) {// this.dao = dao;//}

}

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<bean id="propertyConfigurer"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="location" value="classpath:jdbc.properties"/><property name="ignoreUnresolvablePlaceholders" value="true"/>

</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"><property name="driverClassName" value="${dataSource.driverClassName}"></property><property name="url" value="${dataSource.url}"></property><property name="username" value="${dataSource.username}"></property><property name="password" value="${dataSource.password}"></property>

</bean><!-- Default Connection --><bean id="sessionFactory"

class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"><property name="dataSource" ref="dataSource" /><property name="configLocation">

<value>/WEB-INF/hibernate.cfg.xml</value></property><property name="hibernateProperties">

<props><prop key="hibernate.dialect">net.sf.hibernate.dialect.HSQLDialect</prop><prop key="hibernate.c3p0.minPoolSize">1</prop> <prop key="hibernate.c3p0.maxPoolSize">2</prop><prop key="hibernate.show_sql">true</prop>

</props> </property><property name="schemaUpdate" value="false" />

</bean>

<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory" />

</bean>

<tx:annotation-driven transaction-manager="txManager"/>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"/>

</bean>

<bean id="baseService" abstract="true" lazy-init="true"><property name="jdbcTemplate" ref="jdbcTemplate"/><property name="dataSource" ref="dataSource"/><property name="sessionFactory" ref="sessionFactory"/>

</bean></beans>

コードはすっきり

XML Bean定義(イメージです。拡大しないように)

スライド20よりスッキリだ!

For Beginner

DIコンテナ登場以降のWebアプリ

EIS層中間層Client層

RDBBrowser

Struts

JSFPOJO

Hibernate

iBATIS

DIxAOPコンテナ(オブジェクトの管理やトランザクション制御など)

Spring1~2Seasar2

プレゼンテーション層 ビジネス層 データアクセス層

23

この辺になると僕でも知ってる!

そう、Springの乳児期終盤には、SpringかSeaser2が主に使われていたんじゃ。

For Beginner

本日のハナシ

• 0. Spring誕生

– 2000~2003年 J2EE(EJB)の全盛期

• 1. Spring乳児期

– 2004~2008年 SpringがDIとAOPだった時代

• 2. Spring幼年期

– 2009〜2016年 All in OneからMicroserviceとCloudへ

24

Springの黄金期と近の話じゃ。

For Beginner

Spring 3• Spring3.0

– アノテーションのさらなる強化

• Spring3.1

– JavaConfigの登場

– Java7, Spring Cache

– JavaEEの仕様(Bean Validationなど)の採用

– RESTfullフレームワークとしてのSpring MVC

• Spring3.2

– Hibernate4のフルサポート

• Other Products

– Spring Data、Spring Roo、STS(Spring Tool Suite)

•25

2009

2011

Springの黄金期じゃ

For Beginner

Spring3登場以降のWebアプリ

EIS層中間層Client層

RDBBrowser

Struts

Spring MVC POJO

Hibernate

MyBatis

DIxAOPコンテナ(オブジェクトの管理やトランザクション制御など)

SpringSeasar2

プレゼンテーション層 ビジネス層 データアクセス層

2016年9月に開発が終了

2013年EOL

アノテーションが主流

26

DDDとか!?

そうそう、今のシステムはこんな感じ!

For Beginner

SoEとWebサービス• ここまでのWebアプリは、企業システムで一般的なSoR(System of

Record )の話

• 近年はSoE(Systems of Engagement)なシステムも必要になってきた

– ClientはSoEでServerはSoRという合わせ技もあり

27

EIS層中間層Client層

PCだけじゃなく、携帯端末など

アプリ アプリ

表示だけじゃなくビジネスロジックも

持つWebサービス

隣の部署がやってるやつだ!

ではちょっと、Webサービスの歴史も

見てみることにするかの。

RDB

For Beginner

Webサービス!?

28

2003 2016

UDDIサービスレジストリ

サービス利用者

サービス提供者

WSDL

SOAP

SOA(サービス指向アーキテクチャ)

RESTfulWebサービス

Microservice

Webサービス(初代)

②発見 ①登録

③取得

④利用

電話帳

サービスの利用方法

初代のWebサービスはダメだったんですか?

For Beginner

Webサービス(初代)の失敗• サービスレジストリは誰でも扱える電話帳

– 理想

• 誰でも電話帳にサービスを登録して、誰もがサービスを発見して、利用できる

– 現実

• 電話帳は便所の落書き…

• 結果

– 企業内に閉じた電話帳にしよう

• WSDL不要

– SOAPだね、SOAだね、RESTでいいよね…

29

まぁ、ネット上に晒せばそうなるわなぁ。

SpringのREST対応はどうなっているんですか?

For Beginner

RESTful Webサービス

• Spring MVC

– @Controller

– @RestController

30

Response

ModelController(@RestController)

携帯端末やSPA、Microservice…

Request

ModelController(@Controller)

View

Request

HTMLブラウザ

なるほど!

For Beginner

RESTfulなController

31

@RestController@RequestMapping("/sample")public class SampleController {

@RequestMapping(method = RequestMethod.GET)@ResponseStatus(HttpStatus.OK)public String welcome() {

return "index";}

}

Spring4.3からは、RequestMappingの代わりにGetMappingやPostMappingなどを使うのじゃよ。

For Beginner

Spring 4

• Spring4.0

– Java 8&Java EE 7に対応

– WebSocket、SockJS対応

– 非同期REST対応

• Other Products

– Spring Boot、Spring IO Platform

– Spring Cloud

2013

32

この会場で安く発売してるんだって早く買いに行かなくちゃ!

For Beginner

今、Springが目指しているところ

• Cloud Native!

– Cloud

• Pivotal Cloud Foundary

– Microservice(s)

• Spring Boot

App App

App AppApp

App

App

33

バラバラの部品がどこにあるのか、どうやって分かるんだろう?

Microserviceという部品をいくつも組合わせて、

1つのシステムを作るのじゃよ。

Cloud

Spring BootMicroservice �CI/CD

For Beginner

サービス検出

• Service Discovery(Eurekaの場合)

– Client(Consumer)がAPI(Producer)へ直接アクセスするのではなく、Registryを経由する

– Microserviceの登録と発見/利用

34

Service

ServiceRegistory

Service

1.register 2.discover

3.connect

ProductorEureka Client

ServiceService

Eureka Server

ConsumerEureka Client

Webサービス(初代)にそっくりだ!

EJB1のHome Interfaceにも似ているじゃろ。

For Beginner

MonolithicからMicroservicesへ

•35

����� ���

�����������������

UI���

������

DB����������� ����������������

Monolithicから

Microservices

今まではMonolithicの中の部品化。これからは、monolithicをバラして部品化。

ということじゃな。 これってアジャイルで開発かな?

For Beginner

アジャイル!?

36

1999 2015

デマルコ本

eXtream Programming

大企業でアジャイル採用

1848 1922

共産党宣言

共産主義大国誕生エンゲルス本

アジャイル宣言

賃金労働と資本

アジャイルは当初、プログラマが階級闘争(vs官僚主義的管理者)に勝利し、

プログラマのユートピアを成立させるための運動として、多くのプログラマに支持されたのじゃ。

TDDとか、その後のCI/CDなんてのはオマケじゃ。アジャイルの生い立ちや経過は共産主義と大変似ている。

コミュニティとコミューンなどもな。その後、どうなったかも似るだろうな。

高齢者が壊れ始めたのかな?

共産主義大国崩壊

大企業のアジャイル失敗

※階級闘争

資本家と労働者、管理者とプログラマなど、階級によって格差が存在する階級社会において、階級と階級とのあいだで発生する格差を克服するためにおこなわれる闘争

For Beginner

Microservices成功の鍵(1)• アジャイル

– 成功しない分野

• SI企業による大規模開発

– 官僚的

– 格差が政治的、管理的、賃金的に発生する

– 成功している分野

• ベンチャー的なプロダクト開発、プロトタイプ開発

– 自律的

– 比較的、格差が存在しない(存在しても無視できる)

• Microservices

– 原則

• 1つのサービスをプロダクトとして扱う

– 現実

• サービスを任されたチームが、プロダクトのように扱えるか否かが鍵(そもそも複数チームをまとめるのは大変)

37

格差があるところでアジャイルを実施しようとすれば、必ず階級闘争が起きる。

Microserviceがアジャイルなら階級闘争が起きない環境にしてから、開発すべきじゃ。

確かに!

For Beginner

Microservices成功の鍵(2)

• Microserviceは、EJB1でも、Webサービス(初代)でもない

– そのMicroserviceが、EJB1やWebサービス(初代)で代替可能なら、それはMicroserviceにしなくても良いモノをMicroserviceにしている可能性が高い

38

EJB1やWebサービス(初代)で代替可能なら、それに似た技術の利用を考えるべきじゃ。Microserviceはインフラやチーム管理含め、複雑であるから、

手を出さないで済むのであれば、それにこしたことはない。

For Beginner

本日のハナシ

• 0. Spring誕生

– 2000~2003年 J2EE(EJB)の全盛期

• 1. Spring乳児期

– 2004~2008年 SpringがDIとAOPだった時代

• 2. Spring幼年期

– 2009〜2015年 All in OneからMicroserviceとCloudへ

• おまけ:幼年期の終わりに

39

For Beginner

JavaEEは復活するの?• 再び勢力を伸ばしつつある(ようだ)

– 標準らしいが、不安定なIT業界で標準であることのメリットが全くわから

ない

• EJB1は標準で得だったのか?

– 真似ばかりで機能は少ないし、進化が遅い

– ハコモノを購入しないといけない。結果、標準と謳いながらベンダ固有

の機能を勉強しないといけない

– だから、Springと比較して、優秀なエンジニアが揃わない

• JavaEEでやると決めたプロジェクトは、失敗の匂いがプンプンするのは気のせいか?

40

今更、JSFを使うなんてありえんじゃろ。SIベンダがJavaEEを使うと言い出したら、ハコモノを売りつけられるかもしれないので

ユーザは注意した方がいいぞ。

For Beginner

Spring Bootって使えるの?

• 超楽チンで便利

• ただし、Springの基本的なところも理解せずに使うと、問題発生時にハマる

• Microserviceのようなモノを作るのでなければ、地道に普通に作る方が良い

41

ワシのような高齢者は

Spring Bootを使い始めるとボケてしまう…

For Beginner

Microserviceってどうなの?

• 今までどおりのエンタープライズなシステム(SoR)では、不適当なケースが多い

• エンタープライズのSoE的なところでは、利用できる可能性が高い(成功の鍵は前述どおり)

• インフラも含めて考える必要があるので、今までアプリケーションだけを考えていたエンジニアはステップアップが必要

42

なんでも適材適所じゃよ…

For Beginner

Springはどうなるの?

• Spring 5.0

– M1が2016/7にリリース

– 正式リリースは、2017年4Qを予定

– Java8のみ対応、Reactor

• 今後

– SpringはCloud Nativeに舵をきっているが、エンタープライズ系(SoR)はその辺は無視して、今まで通り

2017

2020

43

ここまでお付合いありがとうよ

For Beginner

44

ライセンスについて• JSUGマスコットアイコン(本スライド左下)が残されている場合に限り、本作品(またそれを元にした派生

作品)の複製・頒布・表示・上演を認めます。

• 非商用目的に限り、本作品(またそれを元にした派生作品)の複製・頒布・表示・上演を認めます。

• 本作品のライセンスを遵守する限り、派生作品を頒布することを許可します。