基本機能について説明します。
ポイント
Spring Frameworkは定義されたBeanをデフォルトでSingletonとして管理しています。変更したい場合にはSpring Frameworkが提供しているBeanスコープ機能を利用してください。
DIコンテナはコンポーネント(クラス)間の依存関係をソースコードから取り除き、実行時まで依存関係を持たないようにするデザインパターンに基づいて作られたコンポーネント群を集中管理するための機能です。
Spring Frameworkでは、オブジェクトが必要とする情報をBean定義ファイルと呼ばれるXML形式またはJava形式のファイルへ定義し、アプリケーション実行時にDIコンテナが定義された情報を注入してオブジェクトのインスタンスを生成します。
DIコンテナを利用する事によって、以下の利点を得る事ができます。
アプリケーションの拡張性を高められる
単体テストが容易になる
コンポーネントの可搬性を高められる
例
XML形式のBean定義ファイル:
… <beans> <!-- Componentスキャンの設定--> <context:component-scan base-package="com.example.component" /> <!-- WebMVC用の基本設定 --> <mvc:annotation-driven></mvc:annotation-driven> <!-- Bean定義--> <bean id="userBean" class="com.example.model.UserBean"/> </beans> |
Java形式のBean定義ファイル:
… @Configuration /* Componentスキャンの設定 */ @ComponentScan(basePackages="com.example.component") /* WebMVC用の基本設定 */ @EnableWebMVC public class WebConfig implements WebMvcConfigurer{ /* Bean定義 */ @Bean public UserBean userBean() { return new UserBean(); } } |
インデックススキャンはアプリケーションの起動時にspring.componentsファイルにある情報を参照してコンポーネントをスキャンする機能です。
インデックススキャンを利用する事によって、クラスパス内の検索に時間がかかる大規模なアプリケーションの起動時間が短くなります。
spring.componentsファイルはアプリケーションのビルド時にEclipseなどの開発ツールの機能を使用して自動生成してください。
例
spring.componentsファイルを自動生成するための設定方法をEclipseを例に説明します。
[Annotation Processing]の設定画面で[Enable annotation processing]にチェックを入れます。
[Factory Path]の設定画面で[Add External JARs]を使ってspring-context-indexerのjarファイルを設定します。
なおSpring Frameworkのアプリケーションをビルドするための設定は“2.4 アプリケーションの開発”を参照して別途行ってください。
注意
1つのアプリケーション内にクラスパススキャンを使用するモジュールとインデックススキャンを使用するモジュールが混在する場合、正常に動作しない場合があります。例えば、アプリケーションはインデックススキャンを使用し、アプリケーションが参照するライブラリはクラスパススキャンを使用する場合です。
いずれかのスキャン方法に統一してください。
バリデーションはオブジェクトとユーザ指定した条件に一致するかをチェックする機能です。
Spring Frameworkは以下の2つのバリデーションを提供しています。
Spring FrameworkのAPIのValidatorインターフェースを使用したバリデーション
Bean Validationを使用したバリデーション
Spring FrameworkのValidatorインターフェースが以下のメソッドを実装するより、オブジェクトを検証できます。
boolean supports(Class)
void validate(Object, Errors)
例
WebMVCのアノテーション付きコントローラでValidatorインターフェースを使用の例を説明します。
オブジェクト定義:
public class UserForm{ private String confirmPassword; private String password; … } |
Validatorインターフェース:
import org.springframework.validation.Validator; public class PasswordValidator implements Validator { public boolean supports(Class clazz) { return UserForm.class.equals(clazz); } public void validate(Object obj, Errors e) { /* 検証条件1とそのエラー内容登録 */ ValidationUtils.rejectIfEmpty(e, "password", "password.empty"); UserForm form = (UserForm) obj; /* 検証条件2 */ if (!form.getPassword().equals(form.getConfirmPassword()) { /* 検証条件2のエラー内容登録 */ e.rejectValue("password", "password.notmatch"); } } } |
コントローラクラス:
@Controller public class UserController { /* Validatorインターフェースをインジェクション */ @Autowired PasswordValidator passwordValidator; @InitBinder /* Validatorインターフェースをコントローラへ登録 */ public void initBinder(WebDataBinder binder) { binder.addValidators(passwordValidator); } @PostMapping("/input") /* form変数を検証し、結果をresultに格納 */ public String inputForm(@Validated UserForm form, BindingResult result) { /* 検証結果の確認 */ if(result.hasErrors()) { return "error"; } return "complete"; } } |
Spring FrameworkはBean Validationと連携して以下のバリデーションが使用できます。
Bean Validationのアノテーションを使ったバリデーションvoid validate(Object, Errors)
Bean ValidationのAPIを直接使うバリデーション
例
WebMVCのアノテーション付きコントローラでBean Validationを使用の例を説明します。
オブジェクト定義:
public class UserForm{ /* Bean Validationのアノテーション */ @Size(max=10) private String name; /* Bean Validationのアノテーション */ @Min(0) @Max(100) private int age; … } |
コントローラクラス:
@Controller |
バリデーターをBeanに設定:
… @Bean public LocalValidatorFactoryBean validator() { return new LocalValidatorFactoryBean(); } … |
StringからIntergerへの変換やArrayからCollectionへの変換、Dateを文字列化する際の整形など、Webアプリケーションで頻繁に使用される型変換機能、およびフォーマット機能のためのService provider interface(SPI)を提供します。
SPIを実装してbean定義内で登録することで、Spring Frameworkが変換を行う際に指定したクラスが使用されます。
例
Javaソース:
class StringToDateConverter implements Converter<String, Date> { public Date convert(String s) { return DateFormat.parse(s); } } |
bean定義ファイル:
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="StringToDateConverter"/> </list> </property> </bean> <mvc:annotation-driven conversion-service="conversionService"/> |
bean定義やアノテーションに#{...}という構文を使用して動的な値を利用できます。
例1は、user.timezoneというシステムプロパティの値を取得する例です。また、例2は、他のbeanの値を取得する例です。例3は、アノテーションを使用した例です。
例
例1 システムプロパティの値を取得:
<bean id="fooSample" class="xxx.FooSampleImpl"> <property name="timezone" value="#{ systemProperties['user.timezone'] }"/> </bean> |
例2 beanの値を取得:
<bean id="fooSample2" class="xxx.fooSample2Impl"> <property name="randomNumber" value="#{ T(java.lang.Math).random() * 100.0 }"/> </bean> <bean id="fooSample3" class="xxx.fooSample3Impl"> <property name="seed" value="#{ fooSample2.randomNumber }"/> </bean> |
例3 アノテーションを使用:
public static class FooSampleImpl{ @Value("#{ systemProperties['user.timezone'] }") private String timezone; public void setTimezone (String timezone){ this.timezone = timezone; } public String getTimezone (){ return this.timezone; } } |
Spring FrameworkはアプリケーションのNULL安全を実現するためのAPIとして@Nullable、@NonNull、@NonNullApi、@NonNullFiledsを提供します。
アプリケーションでこれらのAPIを使用すると、アプリケーションのビルド時にEclipseなどの開発ツールがNULLに対する警告やエラーを出力します。
例
NULLに対する警告やエラーを出力するための設定方法をEclipseを例に説明します。
JavaのCompilerの[Error/Warnings]の設定画面で[Null analysis]の項目の中の[Enable annotation-based null analysis]にチェックを入れます。
1.の設定画面で[Null analysis]の項目の中の[Configure...]をクリックし、[Annotations for Null Specifications]の設定画面を開きます。
[Annotations for Null Specifications]の設定画面で以下の設定を行います。各設定項目の[Secondary annotations]にAPIを設定します。
3-1. [Nullable annotations]にorg.springframework.lang.Nullableを設定します。
3-2. [NonNull annotations]にorg.springframework.lang.NonNullを設定します。
3-3. [NonNullByDefault]にorg.springframework.lang.NonNullApiとorg.springframework.lang.NonNullFieldsを設定します。
なおSpring Frameworkのアプリケーションをビルドするための設定は“2.4 アプリケーションの開発”を参照して別途行ってください。