web-dev-qa-db-ja.com

春のデフォルトスコープはシングルトンですか?

デフォルトのスプリングデフォルトスコープはシングルトンであるため、Springが以下に示すBeanの構成用に2つのオブジェクトを作成している理由を説明していただけますか?

Springの構成は次のとおりです。

<bean id="customer" class="jp.ne.goo.beans.Customer"> 
    <property name="custno" value="100"></property>
    <property name="custName" value="rajasekhar"> </property>
</bean>
<bean id="customer2" class="jp.ne.goo.beans.Customer"> 
    <property name="custno" value="200"></property> 
    <property name="custName" value="siva"></property> 
</bean>
38
Raj

Springのデフォルトスコープisシングルトン。シングルトンであることの意味が、Springがシングルトンを定義する方法と一致しないということだけです。

Springに、異なるIDと同じクラスを持つ2つの別個のBeanを作成するように指示すると、それぞれシングルトンスコープを持つ2つの別個のBeanを取得します。すべてのシングルトンスコープは、同じIDを持つ何かを参照すると、同じBeanインスタンスが返されることを意味します。

Springのドキュメントではシングルトンスコープを定義しています

シングルトンBeanの共有インスタンスは1つだけ管理され、そのBean定義に一致する1つ以上のIDを持つBeanのすべての要求は、Springコンテナーによって返される1つの特定のBeanインスタンスになります。

シングルトンスコープは、同じIDを使用して同じBeanを取得すること、つまりすべてを意味します。 2つのidが同じクラスを参照していないことをテストすると、マップをBeanとして使用する方法が妨げられ、BeanFactoriesで物事をプロキシすることにより複雑になります。 Springのポリシングには、ほとんど利益をもたらさない多くの作業が必要になりますが、代わりにユーザーが何をしているかを知ることを信頼します。

同じBeanに2つの名前を定義する方法は、 alias を使用することです。

Bean定義自体で、id属性で指定された最大1つの名前と、name属性で任意の数の他の名前の組み合わせを使用して、Beanに複数の名前を指定できます。これらの名前は同じBeanの同等のエイリアスにすることができ、アプリケーション内の各コンポーネントがそのコンポーネント自体に固有のBean名を使用して共通の依存関係を参照できるようにするなど、いくつかの状況で役立ちます。

ただし、Beanが実際に定義されているすべてのエイリアスを指定することは必ずしも適切ではありません。他の場所で定義されているBeanのエイリアスを導入することが望ましい場合があります。これは、構成が各サブシステムに分割され、各サブシステムが独自のオブジェクト定義のセットを持っている大規模なシステムでよく見られます。 XMLベースの構成メタデータでは、要素を使用してこれを実現できます。

したがって、Bean構成に名前を追加する場合:

<bean id="customer" name="customer2" 
    class="jp.ne.goo.beans.Customer">
</bean>

または、別の場所で定義されたBeanのエイリアスを作成します。

<alias name="customer" alias="customer2"/>

「customer」と「customer2」は同じBeanインスタンスを参照します。

52
Nathan Hughes

Springのデフォルトスコープはシングルトンであり、スコープをプロトタイプとして明示的に指定しない限り、すべてのインスタンスに対して1つのオブジェクトを作成します。スプリング設定を投稿していません。それを投稿してください、それはより良いアイデアを提供します。

6
Anupama Rao

2つの異なる概念を混同しています。

SpringのWordシングルトンはBeanスコープに使用されます。つまり、Beanはアプリケーション全体に対して1回だけ作成されます。

シングルトンの通常の意味は、GOFパターンを指します。クラスのインスタンスが1つだけ存在することを保証するオブジェクト指向パターンです(少なくともclassLoaderのスコープ内)。

2
Gab

同じクラスの2つのBeanを宣言しています。それは同じではありません。

@Component("springTestClass")
public class SpringTestClass{
     private int randomNumber = 0;
     public SpringTestClass(){
       randomNumber = new Random().nextInt(2000);
     }

     public int getRandomNumber(){
       return this.randomNumber;
     }

}

そして、番号が同じになる2つの場所でこのBeanにアクセスしてみてください。しかし、あなたがしたことは、2つの別個のBeanを作成することでした。

これが機能するかどうかを確認する場合は、次を試してください。

public class Main{
   public static void main(String[] args){
     ApplicationContext ctx = ....;
     SpringTestClass testObject1 = (SpringTestClass)ctx.getBean("springTestClass");
     SpringTestClass testObject2 = (SpringTestClass)ctx.getBean("springTestClass");

    System.out.println(testObject1.getRandomNumber() == testObject2.getRandomNumber());
   }
}

同じコードの場合、このコードはtrueを返します。ただし、SpringTestClassでは、@ Scope( "prototype")アノテーションを追加できます。出力はfalseになります

2
Berrigan

他の人が述べたように、投稿したコードから2つのBeanを作成する必要があります。シングルトンは次のように定義されます(Springのドキュメントから: Singleton Scope

シングルトンBeanの共有インスタンスは1つだけ管理され、そのBean定義に一致する1つ以上のIDを持つBeanのすべての要求は、Springコンテナーによって返される1つの特定のBeanインスタンスになります。

これを明確にするために、「共有インスタンス」の背後にある意味は、上記の後に続く段落で説明されています。

その名前付きBeanに対する後続のすべての要求と参照は、キャッシュされたオブジェクトを返します

シングルトンBeanが作成されると、1つのBeanオブジェクトのみがインスタンス化されてキャッシュされます。これはBeanのみを参照し、Beanがインスタンスである可能性のあるクラスを参照しません。例えば、

<bean id="myBean" class="myPackage.myClass" />

<bean id="myOtherBean1 class="myPackage.myOtherClass1">
    <property name="beanReference1" ref="myBean" />
</bean>
<bean id="myOtherBean2 class="myPackage.myOtherClass2">
    <property name="beanReference2" ref="myBean" />
</bean>

この構成では、「myOtherBean1」と「myOtherBean2」は同じ「myBean」Beanへの参照を持っているため、同じ「myPackage.myClass」インスタンスを参照します。コードを変更して2つ目の「myPackage.myClass」Beanを追加すると、「myBean」とは区別されます。

これを完全に理解するには、他のSpringスコープであるプロトタイプも参照してください。 プロトタイプスコープ のSpringドキュメントから:

Beanデプロイメントの非シングルトンのプロトタイプスコープにより、その特定のBeanに対する要求が行われるたびに、新しいBeanインスタンスが作成されます。

つまり、上記と同じSpring XMLを使用する場合、「myOtherBean1」と「myOtherBean2」はそれぞれ、「myPackage.myClass」の単なるインスタンスである「myBean」の独自のコピーをそれぞれ受け取ることになります。

2
ryoung10

次の例は、@ Beanアノテーション付きメソッドが2回呼び出されることを示しています。

@Configuration
public class AppConfig {

    @Bean
    public ClientService clientService1() {
        ClientServiceImpl clientService = new ClientServiceImpl();
        clientService.setClientDao(clientDao());
        return clientService;
    }

    @Bean
    public ClientService clientService2() {
        ClientServiceImpl clientService = new ClientServiceImpl();
        clientService.setClientDao(clientDao());
        return clientService;
    }

    @Bean
    public ClientDao clientDao() {
        return new ClientDaoImpl();
    }

}

clientDao()は、clientService1()で1回、clientService2()で1回呼び出されています。このメソッドはClientDaoImplの新しいインスタンスを作成して返すため、通常は2つのインスタンス(各サービスに1つ)が必要です。それは間違いなく問題になります。Springでは、インスタンス化されたBeanはデフォルトでシングルトンスコープを持ちます。これが魔法の出番です。すべての@Configurationクラスは、起動時にCGLIBでサブクラス化されます。サブクラスでは、子メソッドは親メソッドを呼び出して新しいインスタンスを作成する前に、キャッシュされた(スコープされた)Beanのコンテナを最初にチェックします。 Spring 3.2以降、CGLIBクラスはorg.springframework.cglibの下に再パッケージ化され、spring-core JAR内に直接含まれているため、CGLIBをクラスパスに追加する必要がなくなったことに注意してください。

0

Spring Singleton BeanはJava Singletonのようには機能しません。

書いたら

ApplicationContext ctx = new ClassPathXmlApplicationContext("MyConfig.xml");
        Customer obj1= (Customer) ctx.getBean("customer");
        Customer obj2 = (Customer) ctx.getBean("customer2");
        System.out.println(obj1 == obj2);
        System.out.println(obj1+ "::" + obj2);

出力が表示される場合、2つの異なるインスタンスが返されます。 Spring Docs Beanによると、シングルトンは1つの共有インスタンスのみが管理され、そのBean定義に一致するIDまたはIDを持つすべてのリクエストBeanが管理されます。ここでは、2つの異なるIDを使用できます。

キー値のペアを管理するSpringコンテナ、ID /名前および値としてのキーはBeanです。

0
gopal jha

SPringでは、シングルトンはSpringコンテナごとに1つのBeanを指し、Javaのようにシングルトンはクラスローダーごとに1つのオブジェクトを指します。

したがって、SpringシングルトンはJavaシングルトンとは異なります。これら2つを混同しないでください。

0
Pritam