Page List

Search on the blog

2012年8月28日火曜日

Spring Framework -オブジェクトの生成-

Spring Frameworkについて、基本的な機能を簡単に紹介します。
  1. オブジェクトの生成
  2. Dependency Injection
  3. Aspect Oriented Programming
の3つの機能を3回のpostに分けて書きます。まずは、オブジェクトの生成から書きます。

XML設定ファイルを利用したオブジェクトの生成
  1. // src/cc/co/goodpreparations/Main.java   
  2.   
  3. package cc.co.goodpreparations;  
  4.   
  5. import org.springframework.context.ApplicationContext;  
  6. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  7.   
  8. public class Main {  
  9.     public static void main(String[] args) {  
  10.         ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");  
  11.           
  12.         Person person =  (Person)context.getBean("person");  
  13.   
  14.         person.saySomething();  
  15.     }  
  16. }  
  1. // src/cc/co/goodpreparations/Person.java  
  2.   
  3. package cc.co.goodpreparations;  
  4.   
  5. public class Person {  
  6.     private String message;  
  7.   
  8.        public void setMessage(String message){  
  9.           this.message  = message;  
  10.        }  
  11.   
  12.        public void saySomething(){  
  13.           System.out.println(message);  
  14.        }  
  15. }  
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!-- src/Beans.xml -->  
  3.   
  4. <beans xmlns="http://www.springframework.org/schema/beans"  
  5.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  6.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  7.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  
  8.   
  9.    <bean id="person" class="cc.co.goodpreparations.Person">  
  10.        <property name="message" value="Hello!"/>  
  11.    </bean>  
  12. </beans>  
XMLファイルにBeanのidとクラスのマッピングを記述します。使用者はidを指定して対応するクラスのオブジェクトを生成します。普通にnewすればいいんじゃない?と思う人もいるかもしれませんが、上記のようにSpringが提供するコンテナからオブジェクトを生成することで、DI/AOPといった機能が使えるようになります。

フィールド値の設定
オブジェクトを生成するときにフィールドの初期値を設定出来ます。同一のクラスから生成されているがフィールド初期値が異なるインスタンスは、異なるBean idをつけることで区別できます。XMLのproperty要素内でフィールドの設定をしていますが、ここで設定するフィールドには必ずsetter(この例の場合はPerson#setMessage)を定義しなければいけません。(JavaBeansなので当然ですが。)
  1. // src/cc/co/goodpreparations/Main.java  
  2. package cc.co.goodpreparations;  
  3.   
  4. import org.springframework.context.ApplicationContext;  
  5. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  6.   
  7. public class Main {  
  8.     public static void main(String[] args) {  
  9.         ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");  
  10.           
  11.         Person taro =  (Person)context.getBean("taro");  
  12.         taro.saySomething();  
  13.           
  14.         Person hanako =  (Person)context.getBean("hanako");  
  15.         hanako.saySomething();  
  16.           
  17.     }  
  18. }  
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!-- src/Beans.xml -->  
  3.   
  4. <beans xmlns="http://www.springframework.org/schema/beans"  
  5.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  6.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  7.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  
  8.   
  9.    <bean id="taro" class="cc.co.goodpreparations.Person">  
  10.        <property name="message" value="ぼく太郎!"/>  
  11.    </bean>  
  12.    <bean id="hanako" class="cc.co.goodpreparations.Person">  
  13.        <property name="message" value="わたし花子!"/>  
  14.    </bean>  
  15. </beans>  
と、このように太郎くんと花子さんを作れます。

Beanのスコープ
Beanを生成するときに、そのスコープを設定することができます。
  1. singleton
  2. prototype
  3. request
  4. session
  5. global-session
3.-5.はWebアプリケーションに特化したものなので、ここでは1.と2.のみを説明します。まずはsingleton
  1. // src/cc/co/goodpreparations/Main.java  
  2. package cc.co.goodpreparations;  
  3.   
  4. import org.springframework.context.ApplicationContext;  
  5. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  6.   
  7. public class Main {  
  8.     public static void main(String[] args) {  
  9.         ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");  
  10.           
  11.         Person person = (Person)context.getBean("person");  
  12.         person.setMessage("Goodbye!");  
  13.         person.saySomething();  
  14.           
  15.         Person person2 = (Person)context.getBean("person");  
  16.         person2.saySomething();  
  17.           
  18.     }  
  19. }  
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!-- src/Beans.xml -->  
  3.   
  4. <beans xmlns="http://www.springframework.org/schema/beans"  
  5.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  6.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  7.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  
  8.   
  9.    <bean id="person" class="cc.co.goodpreparations.Person" scope="singleton">  
  10.        <property name="message" value="Hello!"/>  
  11.    </bean>  
  12. </beans>  
scope="singleton"のところに注目です。名前から想像がつくように、scopeをsingletonにすると同一のidを持つBeanはアプリケーション上で一つしか作られません。つまり、context#getBeanは毎回同じインスタンスの参照を返します。実行結果は
>Goodbye!
>Goodbye!
となります。ちなみにデフォルトのスコープはsingletonです。scope属性を明記しなかった場合、そのBeanのスコープはsingletonになります。
次に、prototypeを試してみます。先ほどと同様の例でscope属性のみをprototypeに変更すると、実行結果は
>Goodbye!
>Hello!
になります。スコープをprototypeにすると、毎回異なるインスタンスが生成されます。

コールバック関数の指定
Beanが生成されたとき/破棄されるときに、何か処理をしたい場合はコールバック関数を指定することができます。
  1. // src/cc/co/goodpreparations/Main.java  
  2. package cc.co.goodpreparations;  
  3.   
  4. import org.springframework.context.ApplicationContext;  
  5. import org.springframework.context.support.AbstractApplicationContext;  
  6. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  7.   
  8. public class Main {  
  9.     public static void main(String[] args) {  
  10.         ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");  
  11.           
  12.         Person person = (Person)context.getBean("person");  
  13.         person.saySomething();  
  14.         person = null;  
  15.          ((AbstractApplicationContext) context).registerShutdownHook();  
  16.     }  
  17. }  
  1. // src/cc/co/goodpreparations/Person.java  
  2. package cc.co.goodpreparations;  
  3.   
  4. public class Person {  
  5.     private String message;  
  6.   
  7.        public void setMessage(String message){  
  8.           this.message  = message;  
  9.        }  
  10.   
  11.        public void saySomething(){  
  12.           System.out.println(message);  
  13.        }  
  14.          
  15.        public void initFunc() {  
  16.            System.out.println("A Person Bean is created!");  
  17.        }  
  18.   
  19.        public void destroyFunc() {  
  20.            System.out.println("A Person Bean is destroyed!");  
  21.        }  
  22. }  
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <!-- src/Beans.xml -->  
  3.   
  4. <beans xmlns="http://www.springframework.org/schema/beans"  
  5.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  6.     xsi:schemaLocation="http://www.springframework.org/schema/beans  
  7.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">  
  8.   
  9.    <bean id="person" class="cc.co.goodpreparations.Person" scope="singleton"  
  10.             init-method="initFunc" destroy-method="destroyFunc">  
  11.        <property name="message" value="Hello!"/>  
  12.    </bean>  
  13. </beans>  
XMLファイルのbean要素のinit-method属性、destroy-method属性にて、コールバックしたい関数を指定することができます。これは便利です。mainメソッド内でAbstractApplicationContext#registerShutdownHookを呼んでいますが、これを呼ぶことで確実にBeanが破棄されdestroy-methodで指定した関数が呼ばれるようにしています。


0 件のコメント:

コメントを投稿