36
企業で使うSpring 鈴木雄介 グロースエクスパートナーズ(株) JSUG/JJUG/SIProp http://www.arclamp.jp/ 2009/6/24

企業におけるSpring@日本springユーザー会20090624

Embed Size (px)

DESCRIPTION

2009年6月24日に行われたJSUG+JGGUG合同勉強会での発表コンテンツです。ブログ:http://www.arclamp.jp/

Citation preview

企業で使うSpring

鈴木雄介グロースエクスパートナーズ(株)

JSUG/JJUG/SIProp

http://www.arclamp.jp/

2009/6/24

はじめに

• 鈴木雄介

– ITゕーキテクト

–今の主な仕事は、顧客企業側に立って標準化の策定/推進を行うこと

–Spring好き。規約より設定重要

•ゕノテーション嫌い

–今日の目標:難しく言わない

–つっこみ歓迎

アジェンダ

• システム開発で大事なこと

• 設計と実装

• なぜSpringを使うのか

• Springの使い方

システム開発で大事なこと

• “安く作る”より”安く使う”

–保守性の高いゕプリ

• ゕプリの枠より作業の枠

–構成管理と自動化

• ベストよりバランス

システム開発で大事なこと

• “安く作る”より”安く使う”

–保守費の割合は60-80%程度。最初に作るコストのうち実装は1/3程度。つまり、実装コストはゕプリの一生からすると7%-13%程度

–時代背景からすると、今後、ますます仕様変更は増えている。拡張性は重要なテーマ

–保守性の高いゕプリケーションを、どう作るのか

参考:保守性

• 保守性とは– 解析性:バグの原因を早く見つけたい

• ソフトウェゕにある欠陥の診断または故障原因の追及、およびソフトウェゕの修正箇所の識別を行なうためのソフトウェゕ製品の能力のこと。

– 変更性:修正するときにめんどくない• 指定された修正を行なうことができるソフトウェゕ製品の能力のこと。修正の実施にはコーデゖング、設計、および仕様書の変更を含みます。

– 安定性:デグレや他影響が少ない• ソフトウェゕの修正による、予期せぬ影響を避けるソフトウェゕ製品の能力のこと。

– 試験性:テストするのが楽• 修正したソフトウェゕの妥当性確認ができるソフトウェゕ製品の能力のこと。

JIS X 0129-1 ソフトウェゕ製品の品質-第1部:品質モデルより

システム開発で大事なこと

• ゕプリの枠より仕事の枠

–個別のゕプリケーションは最適化されていくべき。”平均的”なゕプリケーションは存在しない=標準フレームワークって意味あるの?

•意味ないことはないけど、緩めに設計する必要がある

–仕事の仕方を合わせた方が効果は高い

•構成管理重要。ソースコード、課題

•自動化重要

システム開発で大事なこと

• バランス、バランス、バランス

–すべての利害関係者(未来含む)の調整が重要

–個別最適と全体最適

–“判断は遅く”でも”早く決める”

• コンポーネントの集約は大事

–ただし、機能とクラスは必ず直交するので矛盾が生じやすい。もう、これは運命

機能A

機能B

機能C

設計と実装

クラスA

クラスB

クラスC クラスD

クラスE

クラスF

クラスG

クラスH

同じ機能は、同じクラスに集約

もし変更があれば、すべての機能に影響が出てしまう

設計と実装

• コンポーネントの分離は重要

–実装要件の違いで切れる

•トランザクションの切れ目、ゕーキテクチャの切れ目、UIとデータとロジック

–分業のための分離と、その統合

•互いの作業が、なるべく影響し合わないように、コンポーネントに分離する

•ただし、コンポーネントの統合がビッグバンにならないように注意する

– ンターフェース定義、カプセル化、責務、ロール

設計と実装

• コンポーネントの適切なデザンが要

–ただし、要件分析/概要設計段階で織り込む。実装/詳細設計段階でデザンを変えることは難しいし、そんなコストはかけられない

•再利用=抽象化は設計段階で検討するべき内容

–コードこそ矛盾のない「真の設計書」

•早くコードにするほど矛盾が分かる。プロトタプは設計の仕事

設計と実装

• デザンパターン

– “デザン”パターンは”設計”段階で使うもの

–設計方法論は難しい。美しい方法論は、基本的にあやしい(象牙の塔)

•DDDは、特に難しいと思う。相当、ドメンのビジネス知識がないと無理。

設計と実装

• 未来への対応

–5年後の誰かが悲しまないために

•「なんだよ、この設計/実装!ありえん」

–今後、拡張性や柔軟性がもっと求められる

•小規模は作りなおせばいいじゃんでもOK

–可変性分析

•拡張の方向性や手段について、きちんと確定しておく

なぜSpringを使うのか

• Springはフレームワークのフレームワーク

–個別ゕプリのためにフレームワークを構築するためのフレームワーク

–開発効率よりもSpringらしい”スタル”を重視

–さまざまな3rd Partyプロダクトに対応し、中立性を重んじる。なるべく個性を削らない

– EAIやSOAなどに連携可能

なぜSpringを使うのか

• Springを使う上では、

–オススメのプラクテゖスはあまりないので、自分で決めてからやる

•実装フレームワークもコンポーネント分割も

–設定は確かに複雑になるので担当者を明確にする。あと設定フゔルの分離重要

–使いこなすとすごいけど、設定が難しいプロダクトがある

•WebFlow、Security

なぜSpringを使うのか

• なぜSeasarを使わないのか

–Seasarは優秀なWebゕプリフレームワーク

–開発の効率化、エンジニゕの能力向上に注力

–プラクテゖス(実践)や規約を重視

–適切な部分には、ぜひ使うべき

Springの使い方

• というわけで、非機能の話を中心に

–コンポーネント化

•外部リソースゕクセスの分離

•横断的関心事の分離

–ロギング

–Maven2のプロフゔル機能

外部リソースアクセスの分離

• 例:ログン処理

–1.ログン情報を受け取る

–2.LDAPで認証

–3.DBからユーザー情報を獲得

–4.ログン履歴を保存

–5.認証認可情報を返却する

• 2,3,4は外部リソースゕクセスなので分離するように作る

• シーケンス図

外部リソースアクセスの分離

LoginBL LDAP認証 UserDaoLogin

Logger

ログイン(ログイン情報)

認証フラグ:認証(認証情報)

ユーザー情報:検索(ユーザーID)

ログ(ユーザー情報)

:ユーザー認証情報

外部リソースアクセスの分離

• メリット

–テストがしやすい、デバッグもしやすい

–個別に実装が遅れても逃げられる。たいていは要件確定が遅れる

横断的関心事の分離

• ゕスペクト指向=見地

• 横断的関心事って?

–「メソッドの最初や最後に必ず書く」みたいなもの

–ログ、トランザクション、セキュリテゖ

• ServletFilterは、AOP的

クラス

アスペクト

横断的関心事の分離

• 実装の考え方

–基本はProxyパターンで理解する

LoginBlImpl

Implements

LoginBl

<Interface>

LoginBl

LoginBlImpl

Implements

LoginBl

LoginInterceptor

implements MyBL

<Interface>

MyBl

横断的関心事の分離

• SpringのAOPを使う

–ポントカット:どこに挟むのか

–ゕドバザー:何を挟むのか

• 使いどころ

–性能検証

–ゕクセスログ(内部統制で)

–更新日や更新者の自動設定

ロギング

• ロギングはSLF4JとLogbackがオススメ

– Log4jの作者の新作

• 使い方

–ログ出力:org.slf4j.Logger;

–設定: appenderとlogger

ロギング:APIの使い方import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

public class SampleLogic {

private static Logger logger

= LoggerFactory.getLogger(SampleLogic.class);

public void execute() throws Exception {

if (logger.isTraceEnabled()) {

logger.trace("trace level");

}

if (logger.isDebugEnabled()) {

logger.debug("debug level");

}

logger.info("info level");

logger.warn("warn level");

logger.error("error level");

}

}

ロギング:設定ファイル

<?xml version="1.0" encoding="UTF-8" ?>

<configuration debug="true">

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">

<Target>System.out</Target>

<layout class="ch.qos.logback.classic.PatternLayout">

<Pattern>

%d{HH:mm:ss.SSS} [%thread] %-5level %logger{10} - %msg%n

</Pattern>

</layout>

</appender>

<logger name="org.springframework" level="WARN" />

<logger name="org.apache" level="WARN" />

<root level="DEBUG">

<appender-ref ref="STDOUT" />

</root>

</configuration>

ロギング:マーカー

• マーカー

–マーカーを付けると、出力先を分けることができる。

private IMarkerFactory markerFactory;

@Override

public void logging(User user) {

logger.info(markerFactory.getMarker("login"),

“user loged in “ + user.getName());

}

マーカーを指定

ロギング:マーカー

<appender name=“LOGIN" class="ch.qos.logback.core.ConsoleAppender">

<Target>System.out</Target>

<layout class="ch.qos.logback.classic.PatternLayout">

<Pattern> LOGIN %logger{10} - %msg%n </Pattern>

</layout>

<filter class="jp.arclamp.jsug.sample.log.MarkerFilter">

<marker>login</marker>

<OnMismatch>DENY</OnMismatch>

<OnMatch>ACCEPT</OnMatch>

</filter>

</appender>

フィルターを適用して、出力を制御

ロギング:コンバーター

• コンバート

–要素conversionRule

•属性conversionWord:キーワード

•属性converterClass:出力クラス

• パターンのところで出力が可能

–%{conversionWord}%

• 使いどころ

–ログへのログンユーザー情報出力

ロギング:コンバーター<?xml version="1.0" encoding="UTF-8" ?>

<configuration debug="true">

<conversionRule conversionWord="user"

converterClass=" jp.arclamp.jsug.sample.user.UserInfoConverter" />

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">

<Target>System.out</Target>

<layout class="ch.qos.logback.classic.PatternLayout">

<Pattern>

%d{HH:mm:ss.SSS} [%thread] [%user] %-5level %logger{10} - %msg%n

</Pattern>

</layout>

</appender>

<root level="DEBUG">

<appender-ref ref="STDOUT" />

</root>

</configuration>

ここが置換される

キーワードの設定

コンバータークラスの指定

ロギング:コンバーター

package jp.arclamp.jsug.sample.user;

import jp.arclamp.jsug.sample.log.LogConverterTest;

import ch.qos.logback.classic.pattern.ClassicConverter;

import ch.qos.logback.classic.spi.LoggingEvent;

public class UserInfoConverter extends ClassicConverter {

@Override

public String convert(LoggingEvent event) {

return UserInfoHolder.get();

}

}

継承してコンバーターを作成

出力する文字列を返却

Maven2のプロファイル機能

• 環境毎に設定フゔルの切替を実施

–DB接続設定やログ設定などの切替

–ローカル、IT、本番…など、プロフゔルをカスタマズ可能

• コマンドラン(-P{プロフゔル名})

–mvn eclipse:eclipse –Plocal

–mvn package -Pproduction

Maven2のプロファイル機能

<profiles>

<profile>

<id>local</id>

<build>

<resources>

<resource>

<directory>src/main/resources/local</directory>

<includes>

<include>*.properties</include>

<include>*.xml</include>

</includes>

</resource>

</resources>

</build>

</profile>

プロファイル名の指定

プロファイルで有効になるディレクトリの指定。

Maven2のプロファイル機能

• フォルダ側

クラスパスに通る

他のモノは無視

サンプルコード

• ブログエントリ

• サンプルコード

ライセンスについて

• JSUGマスコットゕコン(本スラド左下)が残されている場合に限り、本作品(またそれを元にした派生作品)の複製・頒布・表示・上演を認めます。

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

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