1
入社1年目のプログラミング初心
者がSpringを学ぶための手引き
2019/12/18
日本Springユーザ会
土岐 孝平
自己紹介
• 土岐 孝平
• Springを使用したシステム開発の支援
• JavaやSpringの研修の講師
• 書籍の執筆
2
[改訂新版]Spring入門
想定する聴講者
• Springを勉強したいけど・・・
– 参考書やサイトに出てくる「用語」がわからない
• アノテーション、Bean、レイヤー、・・・
• どこまでがJavaの話で、どこからがSpringの話なの
かわからない
– 頭の中が整理できない
• 範囲が広くてどこから手をつけていいかわからない
3
「Springを使える」のレベル
• 個別の機能を担当できるレベル
– Springを使ったアプリケーション開発で、アサインされた
機能を(あまり)先輩に頼らずに完成させることができる
• アプリ全体の作りを設計できるレベル
– Springを使ったアプリケーション開発で、全体的なプログ
ラムの役割分担を考えたり、共通の仕組みを設計・実装
できる
4
本セッションの内容
• 「個別の機能を担当できるレベル」がターゲット
– 私が良いと考える学習のステップを紹介
– 各ステップで抑えるとよいポイントや、おすすめの書籍な
どを紹介
– 取り急ぎ知っておくと開発に役立ちそうなことをピックアッ
プして説明
• 「アプリ全体の作りを設計できるレベル」についても
少し触れます
5
良いと思う学習のステップ
• 前提知識を抑えましょう
6
Javaの基本
Web周り SQL、その他DB周り JUnit
Springの基本
(基本的な使い方)
パターン
(レイヤー・MVCなど)
Springの応用
(内部の動き、カスタマイズなど)
設計ノウハウの応用
(各種パターン、UMLなど)
個別の機能を担当できるレベル
アプリ全体の作りを設計できるレベル
アジェンダ
• Springとは?
• 学習のステップ
– Javaの基本
– Web周り
– SQL、その他DB周り
– 設計ノウハウの基本
– JUnit
– Springの基本
• さらなるステップ
7
Springとは?
8
Springとは?
• Javaでアプリケーションを作る際の便利なライブラリ
– 冗長で面倒な部分をSpringが担ってくれる
9
アプリケーション
Spring
Servlet、JDBC、・・・
Java
Java標準の仕組みや他のライブラリ
を直接使うよりも、Springを使ったほ
うがスッキリと効率よくプログラムが
書ける
他ライブラリ
例えば、Servlet
10
・・・
<servlet>
<servlet-name>customerListServlet</servlet-name>
<servlet-class>com.example.CustomerListServlet
</servlet>
<servlet-mapping>
<servlet-name>customerListServlet</servlet-name>
<url-pattern>/customerList</url-pattern>
</servlet-mapping>
・・・
public class CustomerListServlet extends HttpServlet {
protected void doGet(
HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String groupNo = req.getParameter("groupNo");
・・・
req.getRequestDispatcher(
"/WEB-INF/jsp/customerList.jsp")
.forward(req, resp);
}
}
【Java標準のServletを直接使った場合】
web.xml
【Springを使った場合】
@Controller
public class CustomerListController {
@GetMapping("/customerList")
public String cusomerList(
@RequestParam String groupNo) {
・・・
return "customerList";
}
}
・リクエストとメソッドの対応付けが簡単
・リクエストのデータを簡単に取得できる
例えば、JDBC
11
public int getCustomerCount(String groupNo) throws SQLException {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = DriverManager.getConnection(
"jdbc:postgresql://db.example.com/exampleDb", "user01", "pass01");
ps = con.prepareStatement(
"SELECT count(*) FROM customer WHERE group_no=?");
ps.setString(1, groupNo);
rs = ps.executeQuery();
if (rs.next()) {
return rs.getInt(0);
}
throw new RuntimeException("データが見つかりませんでした");
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
log.error("ResultSetのクローズに失敗しました", e);
}
}
・・・省略
}
}
public int getCustomerCount(String groupNo) {
return jdbcTemplate.queryForObject(
"SELECT count(*) FROM customer WHERE group_no=?",
Integer.class, groupNo);
}
【Java標準のJDBCを直接使った場合】 【Springを使った場合】
自動的に以下が行われる
・Connectionの取得
・PreparedStatememtの取得
・SQLの実行/ResultSetの取得
・ResultSetの開放
・PreparedStatementの開放
・Connectionの開放
さまざまな機能・技術に対応
• セキュリティ
• バッチ処理
• システム間連携
• NoSQL
• クラウド
• ・・・
12
その他の情報
• 2003年にversion1.0がリリースされたオープンソー
スのライブラリ
• ライセンス:Apache License 2.0
– カスタマイズして商用で利用しても問題ない
• Pivotal社が開発
– Pivotal:2013年にVMWareとEMC(現在はDell EMC)が共同で設立
した会社
– Springは、クラウドなどのビジネスのキーとなる技術という位置づけ
• 大手Slerのフレームワークのベースとして採用され
ている
– NTTデータ:Terasoluna
– 日本ユニシス:Maia
13
Javaの基本
学習のステップ
14
Javaの基本
Web周り SQL、その他DB周り JUnit
Springの基本
(基本的な使い方)
パターン
(レイヤー・MVCなど)
新人の方が抱えてる(であろう)悩み
• 新人研修でJavaの知識を詰め込んだが、定着して
いない
• 先輩が使う用語がわからず、しゃべってる内容が理
解できない
15
いま一度Javaの用語を整理しましょう
・先輩との会話がスムーズになる
・体系的な知識が身につく
Javaの用語のいろいろ
• インスタンス
• デフォルトコンストラクタ
• オーバーロード
• オーバーライド
• ポリモフィズム
• アクセス修飾子
• フィールド(属性)
• ローカル変数
• thisとsuper
• 具象クラス
• チェック例外と非チェッ
ク例外
• スレッド
• アノテーション
• ガベージコレクション
16
本セッションで触れる箇所
~よく使うけど、通じてないなと感じることが多い用語
フィールド(属性)とローカル変数
• どれがフィールドでどれがローカル変数でしょう?
17
public class OrderService {
private int totalPrice;
public int calclateOrderPrice(int orderNo) {
List<OrderDetail> details = DBから取得;
totalPrice = 0;
for (OrderDetail detail : details) {
totalPrice += detail.getPrice();
}
return totalPrice;
}
}
フィールド(属性)とローカル変数
18
public class OrderService {
private int totalPrice;
public int calclateOrderPrice(int orderNo) {
List<OrderDetail> details = DBから取得;
totalPrice = 0;
for (OrderDetail detail : details) {
totalPrice += detail.getPrice();
}
return totalPrice;
}
}
【フィールド】
クラスの中、
メソッドの外で宣言した変数
【ローカル変数】
メソッドの中で
宣言した変数
《参考》メソッドの引数(上記のorderNo)は、ローカル変数ではないが、特徴が似ている
フィールドの特徴
• オブジェクトに対してフィー
ルドのメモリ領域が確保さ
れる
• あるメソッドで更新したデー
タを、他のメソッドで参照で
きる
19
public class OrderService {
private int totalPrice;
public int calclateOrderPrice(
int orderNo) {
List<OrderDetail> details = DBから取
得;
totalPrice = 0;
for (OrderDetail detail : details) {
totalPrice += detail.getPrice();
}
・・・
}
public boolean isOver1000() {
return totalPrice > 1000;
}
}
オブジェクト
toalPrice
オブジェクト
totalPrice 1000
calclateOrderPrice
メソッド
isOver1000メソッド
マルチスレッド※とフィールド
• 複数のスレッドが1つのオブジ
ェクトを使うときはフィールドに
気をつける
– あるスレッドで書き換えたフィー
ルドを、他のスレッドも参照する
20
スレッドA
スレッドB
オブジェクト
totalPrice
他のユーザのデータを表示
してしまう危険性がある
public class OrderService {
private int totalPrice;
public int calclateOrderPrice(
int orderNo) {
List<OrderDetail> details =
DBから取得;
totalPrice = 0;
for (OrderDetail detail : details) {
totalPrice += detail.getPrice();
}
return totalPrice;
}
}
※ 複数の処理が同時に実行されること。
1つ1つの実行単位をスレッドと呼ぶ
calclateOrderPrice
メソッド
calclateOrderPrice
メソッド
ローカル変数の特徴
• スレッドに対して変数のメモリ領域が確保される
– マルチスレッドでも安全(スレッドセーフ)
21
public class OrderService {
private int totalPrice;
public int calclateOrderPrice(
int orderNo) {
List<OrderDetail> details =
DBから取得;
int totalPrice = 0;
for (OrderDetail detail : details) {
totalPrice += detail.getPrice();
}
return totalPrice;
}
}
orderNo
details
detail
スレッドAのcalclateOrderPrice呼び出し
totalPrice
orderNo
details
detail
スレッドBのcalclateOrderPrice呼び出し
totalPrice
おすすめの書籍
• オラクル認定資格教科書 Javaプログラマ Silver
SE11(翔泳社)
– 体系的に用語を抑えることができる
– 資格を取ることが目的ではなく、知識をつけることが目的
• 目標を明確にするという意味で資格を取るとよい
22
Web周り
学習のステップ
23
Javaの基本
Web周り SQL、その他DB周り JUnit
Springの基本
(基本的な使い方)
パターン
(レイヤー・MVCなど)
Web周りの知識のいろいろ※
【Javaに限らない知識】
• HTTPプロトコル
• HTML/CSS/JavaScript
• Web セキュリティ
• REST API
【Java関連】
• Servlet
• JSP
24
本セッションでは触れません
詳しくなくてもよいが、基本的なことは知っておいたほうがよい
※ SPA関連は含んでいません
おすすめの勉強法
• 入門書で「広く浅く」学ぶ
• おすすめの書籍
– スッキリわかるサーブレット&JSP(インプレス)
• HTMLの話から始まって、サーブレット&JSP
だけでなく、JDBCや、MVC・DAOパターンの
話も分かりやすく解説されている
– スラスラわかるJavaScript(翔泳社)
• JavaScriptだけでなく、HTML・CSS・jQuery・
デバッガの使い方も解説されている
– 安全なウェブサイトの作り方(IPA)
• Webセキュリティの攻撃と対策が分かりやすく
体系的にまとまっている
• IPAのサイトから無料でダウンロードできる
25
SQL、その他DB周り
学習のステップ
26
Javaの基本
Web周り SQL、その他DB周り JUnit
Springの基本
(基本的な使い方)
パターン
(レイヤー・MVCなど)
抑えておくとよい知識のいろいろ
• SQL
– 結合
– グループ関数
• トランザクション
– コミット・ロールバック
– ロングトランザクション
• 排他制御
– ロストアップデート
– 楽観ロック・悲観ロック
– デッドロック
• データモデル
– 多重度
– 交差(中間)テーブル
• Java関連
– JDBC
27
本セッションでは触れません
おすすめの書籍・サイト
• SQLの絵本 第2版(翔泳社)
– 絵で説明しているためイメージしやすい
• 多重度・交差テーブル
– http://gomocool.net/gomokulog/?p=8
20
• TERASOLUNA Server Framework
for Java (5.x) Development
Guideline 「排他制御」の節
– 多くの情報がわかりやすく整理されてい
る(プログラム初心者には少し難しめ)
28
《参考》SQLの絵本の絵の例(結合の種類)
29
a
1
2
5
b
1
2
7
テーブル内部結合
a
1
2
b
1
2
左外部結合
a
1
2
5
b
1
2
NULL
右外部結合
a
1
2
NULL
b
1
2
7
全外部結合
a
1
2
5
NULL
b
1
2
NULL
7
交差結合
a
1
1
1
2
2
2
5
5
5
b
1
2
7
1
2
7
1
2
7
パターン
学習のステップ
30
Javaの基本
Web周り SQL、その他DB周り JUnit
Springの基本
(基本的な使い方)
パターン
(レイヤー・MVCなど)
パターンとは?
• プログラムの設計方法を汎用的に整理したもの
– さまざまな人がさまざまなパターンを考えている
– 想定する問題ごとにカタログ化されている
• よく言及されるパターン(知っておくとよい)
– レイヤー、MVC、DAO、シングルトン
31
本セッションで触れる箇所
レイヤーとは?
• プログラムを分割する際のノウハウ
• プログラムを層として表現し、上位の
層のプログラムが下位の層のプログ
ラムに依存する(使用する)という考
え方
• レイヤーのルール
– 下位の層が、上位の層を利用してはい
けない
– 層を飛び越えてはならない
※ 許容する考え方もある
• レイヤーのメリット
– 上位の層の変更が下位の層に影響しない
– 下位の層の変更を直上の層が吸収すること
で影響範囲を小さくできる
Webアプリケーションのレイヤー
• 3層レイヤーの例
– プレゼンテーション層:画面周りの処理
– ビジネス層:業務ロジック
– データアクセス層:データアクセス(SQL実行)の処理
プレゼンテーション層
ビジネス層
データアクセス層
Controller
Service
(業務ロジック)
Dao
(データアクセス)
ブラウザ
View
Entity
(業務データ)
データベース
依存の方向
依存は一方通行!
レイヤーを意識していないアプリ
• 1つのクラスが複数の役割を担って複雑になる
• 同じ処理を複数のところで記述してしまう
• 相互依存になってしまい修正が難しくなる
HTTP&
業務ロジック
SQL実行
業務ロジック&
SQL実行
業務データ
おすすめの書籍
• スッキリわかるサーブレット&JSP(インプレス)
– 解説されているMVC、DAOパターンを理解する
35
パターンについて詳細に解説されている書
籍はたくさんあるが、「個別の機能を担当で
きるレベル」を目指すにあたってはひとまず
これだけでも十分と思われる
再掲
JUnit
学習のステップ
36
Javaの基本
Web周り SQL、その他DB周り JUnit
Springの基本
(基本的な使い方)
パターン
(レイヤー・MVCなど)
抑えておくとよいこと
• JUnitの基本のアノテーション
– JUnit4: @Test、@Before、@After
– JUnit5: @Test、@BeforeEach、@AfterEach
• アサーションライブラリ
– Hamcrest
もしくは
– AssertJ
• モックライブラリ
– Mockito
37
本セッションでは触れません
おすすめのサイト
• JUnitの概要
– http://www.mitchy-world.jp/java/test/junit4.htm
• Hamcrestの詳しい使い方
– https://qiita.com/opengl-
8080/items/e57dab6e1fa5940850a3
• AssertJの詳しい使い方
– https://qiita.com/opengl-
8080/items/b07307ab0d33422be9c5
• Mockitoの概要
– http://niwaka.hateblo.jp/entry/2015/09/19/171610
38
Springの基本
学習のステップ
39
Javaの基本
Web周り SQL、その他DB周り JUnit
Springの基本
(基本的な使い方)
パターン
(レイヤー・MVCなど)
「Spring」の範囲は非常に広い
• Springのコア
– DI・AOP
• テストサポート
• データアクセス
• Spring MVC
• Spring Security
• Spring Boot
• Spring Session
• Spring Data
• Spring Actuator
• Spring Batch
• Spring Integration
• Spring Cloud
• Reactive
・・・
40
Spring XXXがたくさんある・・・
抑えておくとよい知識
• DIコンテナ
• ステレオタイプアノテーション
• @Autowired
• データアクセス
• トランザクション制御
• Spring MVC
• Springのテストサポート
41
本セッションで触れる箇所
DIコンテナ
• Springが提供するオブジェクトを管理する入れ物
• 管理されているオブジェクトのことを「Bean」と呼ぶ
• Beanの特徴
– 他のオブジェクトをDI (後述)で簡単に保持できる
– オブジェクトをシングルトン※にするのが簡単
42
DIコンテナ
オブジェクトA
オブジェクトB
BeanBean
※1つのオブジェクトを使いまわす作りのこと
Beanとして管理してもらう方法
• Beanとして管理してほしいクラスに「ステレオタイプ
アノテーション」をつける
• DIコンテナは、起動時にステレオタイプアノテーショ
ンがついたクラスを探して(コンポーネントスキャン)、
見つけるとオブジェクトを作ってDIコンテナで管理す
る
43
@Service
public class CustomerService {
・・・
}
@Repository
public class OrderDao {
・・・
}
ステレオタイプアノテーション主な種類
44
種類 使い分け 付加機能
@Controller Controllerの役割のクラスに
付与する
Spring MVCと連携できる
@Service Service(業務ロジック)の役割
のクラスに付与
なし
@Repository データアクセス(Daoなど)の役
割のクラスに付与
DB周りの例外を、Springの
例外に変換してくれる
@Component 上記以外の役割のクラスに付
与
なし
オブジェクトを保持するには?
• 手っ取り早い方法
– new演算子でオブジェクトを作成する
45
@Service
public class CustomerService {
public int getTotalPrice(String orderNo) {
OrderDao dao = new OrderDao();
List<OrderDetail> details =
dao.getDetails(orderNo)
・・・
}
}
@Repository
public class OrderDao {
public List<OrderDetail> getDetails (
String orderNo) {
return データベースから取得;
}
}
【問題点】
CustomerServiceをテストするときに、CustomerDaoをモック(偽
物のオブジェクト)にすり替えることができない
OrderService OrderDao
Springを利用した場合
• オブジェクトの作成はSpringが行う
– ステレオタイプアノテーションの@RepositoryをSpringが検知
• Springがオブジェクトを渡してくれる
– オブジェクトを外部から渡してもらうことをインジェクションと呼ぶ
– 長い言葉だと、Dependency Injection、略してDIとも呼ぶ
– @Autowiredでインジェクションを指示する
46
@Service
public class CustomerService {
@Autowired
private CustomerDao dao;
public int getTotalPrice(String orderNo) {
List<OrderDetail> details =
dao.getDetails(orderNo)
・・・
}
}
@Repository
public class OrderDao {
public List<OrderDetail> getDetails (
String orderNo) {
return データベースから取得;
}
}
テストのときにCustomerDaoをモックにす
り替えることができる(モックライブラリを
使うのが一般的)
OrderService OrderDao
Spring 作成渡す
シングルトンの実現が容易
• 1つのオブジェクトを使いまわすことが簡単
– 余計なメモリの消費を防げる
47
ReportServiceオブジェクト
orderDao
OrderServiceオブジェクト
orderDao
OrderDaoオブジェクトDIコンテナ
@Autowired
@Autowired
インジェクション
インジェクション
シングルトンの注意点
• スレッドごとに中身が変わるデータをフィールドに入
れてはいけない
– スレッドセーフ(マルチスレッドで利用しても安全なこと)で
はなくなってしまう
48
スレッドA
スレッドB
オブジェクト
totalPrice
他のユーザのデータを表示
してしまう危険性がある
@Service
public class OrderService {
private int totalPrice;
public int calclateOrderPrice(
int orderNo) {
List<OrderDetail> details =
DBから取得;
totalPrice = 0;
for (OrderDetail detail : details) {
totalPrice += detail.getPrice();
}
return totalPrice;
}
}
スレッドセーフなオブジェクト
• スレッドごとに中身が変わるデータはローカル変数
を利用する
49
@Service
public class OrderService {
private int totalPrice;
public int calclateOrderPrice(
int orderNo) {
List<OrderDetail> details =
DBから取得;
int totalPrice = 0;
for (OrderDetail detail : details) {
totalPrice += detail.getPrice();
}
return totalPrice;
}
}
《補足》Beanで管理しないオブジェクト
• スレッドごとに中身が変わるオブジェクトは原則としてBeanで
管理しない
– 例:リクエストに応じてDBから取得したデータをフィールドにもつオブ
ジェクト
– Beanは原則シングルトンなので、スレッドセーフにならない
50
@Repository
public class OrderDao {
public List<OrderDetail> getDetails (
String orderNo) {
・・・
OrderDetail detail = new OrderDetail();
detail.setItemNo(rs.getString("item_no"));
detail.setUnitPrice(rs.getInt("unit_price"));
・・・
return list;
}
}
オブジェクト
i001itemNo
300unitPrice
オブジェクト
i999itemNo
100unitPrice
Aさんの注文
Bさんの注文
おすすめの資料(過去のJSUG資料)
51
重要度※ 読む順番 用途 タイトル・リンク
★★★ 4
開発前の注意点や、知っておい
たほうがよいこと
これからSpringを使う開発者が知っておくべきこと
https://www.slideshare.net/KouheiToki/spring-
121307860
Springを何となく使ってる人が抑えるべきポイント
https://www.slideshare.net/KouheiToki/spring-
66768974
★★★
3
Spring MVCを詳しく知るハンズ
オン(HTMLをサーバで描画する
アプリの場合に読む)
これから始めるSpringのWebアプリケーション 〜ハンズ
オン編〜
https://github.com/wataru-o/springfest2017-handson
★★★ 3
Spring MVC RESTの概要を知る
(REST APIのアプリの場合に読
む)
Spring Bootで作るRESTful Web Service
https://www.slideshare.net/WataruOhno/spring-fest-
2018-spring-bootrestful-web-service
★★ 1
Springを使ったアプリがどんな感
じかを掴む
これから始めるSpringのWebアプリケーション
https://www.slideshare.net/KouheiToki/springweb-
82685380
★★ 2
Springを使う前と、使った後の差
を体験できるハンズオン
Springを使ったWebアプリにリファクタリングしよう
https://github.com/KouheiToki/jsug-handson-
20161118
★★ 5
Spring Bootを使う前と、使った後
の差を体験できるハンズオン
Spring 5 & Spring Boot 2ハンズオン
https://github.com/MasatoshiTada/spring5-boot2-
handson
★ 6
DIの考え方とSpringのDIコンテナ
の基本を知る
今さら聞けないDiとspring
https://www.slideshare.net/KouheiToki/dispring
※重要度の目安:開発にあたって「★ ★ ★必ず目を通す」「★★余裕があれば目を通す」「★興味があれば目を通す」
さらなるステップ
52
さらなるステップ
• 「アプリ全体の作りを設計できるレベル」を目指す
53
英語の文章への抵抗をなくす
Springの応用
(内部の動き、カスタマイズなど)
設計ノウハウ
(各種パターン、UMLなど)
英語の文章への抵抗をなくす
• 英語で公開されてる情報量のほうが、日本語のもの
より格段に多いし早い
• Springをはじめとするさまざまな製品のマニュアル
は英語で書かれている
– エラー時のメッセージも英語
• 抵抗をなくすお勧めの方法
– 英語の技術本を1冊読み通す
54
Springの応用
• まず抑えるとよい部分
– Spring Security
– Spring Bootのオートコンフィグレーション
• その他、細かい使い方や内部の動き
• おすすめの書籍・サイト
– [改訂新版]Spring入門(技術評論社)
– TERASOLUNA Server Framework for Java (5.x)
Development Guideline
– オートコンフィグレーションの仕組み
• https://qiita.com/kazuki43zoo/items/8645d9765edd1
1c6f1dd
• 資格勉強:Spring Professional Certification(Pivotal) 55
設計ノウハウ
• 各種パターン
– 「すぐに現場に適用する」という目的ではなく、設計
するときの視点や考え方の参考にする
– さまざまな文献で引用されることがあるので、知っ
ておくと役立つ
• UML
– 設計書を書くためではなく、設計時の思考を絵にす
る道具として有効
• おすすめの書籍
– 各種パターン
• Patterns of Enterprise Application
Architecture (Addison-Wesley Professional)
• Design Patterns (Addison-Wesley
Professional)
– UML
• UML Distilled(Addison-Wesley
Professional) 56
まとめ
57
良いと思う学習のステップ
• 前提知識を抑えましょう
58
Javaの基本
Web周り SQL、その他DB周り JUnit
Springの基本
(基本的な使い方)
パターン
(レイヤー・MVCなど)
Springの応用
(内部の動き、カスタマイズなど)
設計ノウハウ
(各種パターン、UMLなど)
個別の機能を担当できるレベル
アプリ全体の作りを設計できるレベル
59
ご清聴ありがとうございました
60
ライセンスについて
• JSUGマスコットアイコン(本スライド左下)が残されている場合に限り、本作品(またそれを元にした派生
作品)の複製・頒布・表示・上演を認めます。
• 非商用目的に限り、本作品(またそれを元にした派生作品)の複製・頒布・表示・上演を認めます。
• 本作品のライセンスを遵守する限り、派生作品を頒布することを許可します。

入社1年目のプログラミング初心者がSpringを学ぶための手引き