spring beanのscope実験


もっと読む
    springのbeanはspringコンテキストの範囲内ではデフォルトは一例であることはよく知られているが、beanタグのscope属性明示的なマークをprototypeとすることによって、非一例に変えることができる。
    以下はいくつかのプログラムを書いてこの結論を検証します。プログラムは一つの調合者インターフェースRefererと被調合者インターフェースRefereeを使います。
package refer;

public interface Referer 
{
	void order();
}
package refer;

public interface Referee
{
	void speak();
}
ChenRefererは调节者インターフェースを実现し、gurefereeは调节者インターフェースを実现しました。
package refer;

public class ChenReferer implements Referer
{
	public Referee guang;

	public Referee getGuang()
	{
		return guang;
	}

	public void setGuang(Referee guang)
	{
		this.guang = guang;
	}
	
	public void order()
	{
		System.out.println("I am chen and my address is: " + this.toString().split("@")[1]);
		guang.speak();
	}
}
package refer;

public class guangReferee implements Referee
{
	public void speak() {
		System.out.println("I am guang and my address is: " + this.toString().split("@")[1]);
	}
}
调节者と被调节者の実现クラスの组み合わせ情报を同じカバンの下のbeans.xml配置ファイルに入れます。


	
		
	
	
	
	
注意bean chen属性scope=「prototype」は設定されていません。
次は主な方法です。
package refer;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestDemo 
{
	public static void main(String[] args)
	{
		ApplicationContext context = new ClassPathXmlApplicationContext("refer/beans.xml");
		Referer chen = (Referer) context.getBean("chen");
		Referer chen1 = (Referer) context.getBean("chen");
		
		chen.order();
		chen1.order();
	}
}
主な方法はspringプロファイルをロードしています。11行目と12行目はそれぞれ2回のspring容器からIDをchenのbeanとして取り出して、実行しています。コンソール表示:
I am chen and my address is:259 c 259 c
I am gung and my address is:608 a 608 a
I am chen and my address is:259 c 259 c
I am gung and my address is:608 a 608 a
二つのchenの物理アドレスは同じであり、容器からbeanを2回取り出すが、得られたのは同じChenRefererオブジェクトだけで、コンテキスト範囲内の単一の例を証明している。
次に、beans.xmlのbean cheenに属性値scopeの声明を追加します。


	
		
	
	
	
		
	
	
	
	
メインメソッドを再実行した結果、
I am chen and my address is:1861856
I am gung and my address is:58 cc
I am chen and my address is:dc 00 dc 0
I am gung and my address is:58 cc
二回のchen物理アドレスは違っていて、二回目のgetBean法呼び出し時にbean容器がChenRefererオブジェクトを再生成することを証明しています。
同じような場合は、引用された対象に適用されます。私たちは新たにコーディネーターのLingRefererを追加します。
package refer;

public class LingReferer implements Referer
{
	public Referee guang;

	public Referee getGuang()
	{
		return guang;
	}

	public void setGuang(Referee guang)
	{
		this.guang = guang;
	}
	
	public void order()
	{
		System.out.println("I am ling and my address is: " + this.toString().split("@")[1]);
		guang.speak();
	}
}
beans.xmlファイルも次に修正します。


	
		
	
	
	
		
	
	
	
	
この時のbean guangのscopeはprototypeではありません。
修正後の主な方法:
package refer;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestDemo 
{
	public static void main(String[] args)
	{
		ApplicationContext context = new ClassPathXmlApplicationContext("refer/beans.xml");
		Referer chen = (Referer) context.getBean("chen");
		Referer ling = (Referer) context.getBean("ling");
		
		chen.order();
		ling.order();
	}
}
実行した結果:
I am chen and my address is:371 a 371 a
I am gung and my address is:6714714
I am ling and my address is:259 c 259 c
I am gung and my address is:6714714
二つの異なる調合者のchenとlingはそれぞれgungを引用していますが、bean gurngは文脈の一例ではないので、それらは同じgungRefereeオブジェクトを参照しています。
beans.xmlファイルを再度変更すると以下のようになります。


	
		
	
	
	
		
	
	
	
	
主な方法は変わらず、実行します。
I am chen and my address is:b 440 b 44
I am gung and my address is:d 520 d 52
I am ling and my address is:5 cm 45 ca 4
I am guang and my address is:3 aac 3 aac
bean gurngは文脈が単一の例ではないと設定されているので、実行期間においてspring容器はそれぞれ二つの異なるgungRefereeオブジェクトを生成し、chenとlingはそれぞれそれらを参照している。