この前、Spring frameworkを自学した時のメモでした。。
1、歴史&基本概念
Springは2002年、 Rod Jahnsonは自分の名作「Expert One-on-One J2EE Design and Development」にて、
初めてSpringの中核概念を提出した。最初はEJBを代替するためですが、10何年をかけて、豊富な機能を
実現できて、Javaプラットフォームの中で、メインオープンソースアプリケーションフレームワークになりました。
メインモジュールは以下通り
●Spring Framework
Spring生態系の基礎で、ほかのモジュールは全部Spring Frameworkの上に動作する。
●Spring Boot
開発Framework、Developerは迅速にアプリケーションを作ることができる。
ほかのサードパーティーモジュール( MyBatisなど)を簡単にインテグレートして、
簡単な配置すれば、使える。JSONのフォーマットをサポートする。
●Spring Cloud
分散開発のためのモジュールを収集して、Developerはこれらのモジュール
を使って、microservicesを迅速に構築できる。
以下のイメージです(公式サイトからの図)
Springの中核仕組みは IoC(制御の反転)とAOP(アスペクト指向プログラミング)であり、
IoCについて、
伝統的な方式について、クラスのインスタンスを欲しいとき、Developerは自分でNewして、使うこと。
SpringのIocについて、クラスのインスタンスの作りは全部FrameworkのIocContainerは遣ってくれるので、
Developerはただ直接使えます。伝統式と比べて、流れは反転されましたので、制御の反転になります。
伝統式、以下のクラスの場合、
public class Book {
private String id;
private String name;
private int price;
}
インスタンスは欲しいとき、以下のNewで作る。
Book bk = new Book();
SpringのIoCContainerに任せる場合、以下のことをやれば実現できる。
●XML配置で実現するパターン
①空のSpring Starterプロジェクトを作成
②resourcesフォルダに、、以下通りの空のIoCbeans.xmlとのXMLを作成して
<Beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
</beans>
③beanタグを使って、IoCContainerはインスタンスを作ってくれる。
<bean id="book" class="learningAOP.learningAOP.bean.Book"></bean>
●id:インスタンス名
class:対象クラス
以下の例はConstructorなしの状態でインスタンスが作られる。
④インスタンスを取得
●idを使って、取得
//ApplicationContextでXMLをロード
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("IoCbeans.xml");
//bookとのIDでインスタンスを取得
Book book = (Book) applicationContext.getBean("book");
System.out.println(book);
Outputは以下
ID: nullname: null price: 0
各プロパティの値は全部初期値になる。プロパティの値を設定したい場合、XMLの定義は
以下通りに変更すればいいです。
PS:BookクラスのGetter&Setterは必須
<bean id="book" class="learningAOP.learningAOP.bean.Book">
<property name="ID" value="1"></property>
<property name="name" value="demo"></property>
<property name="price" value="100"></property>
</bean>
もう一回実行した結果
ID: 1name: demo price: 100
●クラスのタイプを使って、取得
//Beanのクラスを使って、インスタンスを取得
Book book1 = applicationContext.getBean(Book.class);
System.out.println(book1);
デメリットは同じクラスの複数のBean定義があれば、異常が発生する。
⑤Constructorがある時
//引数付けConstructor
public Book(String id, String name, int price) {
this.ID = id;
this.name = name;
this.price = price;
}
XMLのBean定義は以下通り
<bean id="bookcon" class="learningAOP.learningAOP.bean.Book">
<constructor-arg name="ID" value="2">
<constructor-arg name="name" value="demo2">
<constructor-arg name="price" value="200">
</bean>
Main関数で、以下通りにインスタンスを取得
Book bookcon= (Book)applicationContext.getBean("bookcon");
System.out.println(bookcon);
Outputは
ID: 2 name: demo2 price: 200
以上は単純なインスタンスの制御ですが、複数のクラスが存在、かつ依存関係がある時、
以下通りに実現する(
Bookクラスの中で、Authorとのクラスのメンバーがある、要はBookクラスはAuthorクラスを依存する。
public class Author {
private String ID;
private String name;
private int age;
}
Bookクラスは以下
public class Book {
private String id;
private String name;
private int price;
private Author author
}
PS:Getter&Setterここで省略
XMLにて、以下通りに依存関係を定義する
<bean id="author" class="learningAOP.learningAOP.bean.Author">
<property name="ID" value="1">
<property name="name" value="demo">
<property name="age" value="30">
</bean>
<bean id="book" class="learningAOP.learningAOP.bean.Book">
<property name="ID" value="1">
<property name="name" value="demo">
<property name="price" value="100">
<property name="author" ref="author">
ここで、refで、クラス間の依存関係を表明して、DI(Dependency Injection)を呼び
IoCの具体的実現し方である。
実行してみたら
Book bookcon= (Book)applicationContext.getBean("book");
System.out.println(bookcon)
Outputは
ID: 1 name: demo price: 100 Author: ID: 1 name: demo age: 30
PS:最新Spring bootでは、Ioc&DIについて、全部アノテーションで実現する。