web-dev-qa-db-ja.com

シングルトンデザインパターンとSpringコンテナのシングルトンBean

SpringコンテナにはデフォルトでシングルトンとしてBeanがありますが、Springフレームワークに基づいたWebアプリケーションがある場合、その場合は、単にSpringを介してBeanを作成するのではなく、Singletonデザインパターンを実装してグローバルデータを保持する必要があります。

私が実際に尋ねたいことを説明できない場合は、ご容赦ください。

86
Peeyush

SpringのシングルトンBeanとシングルトンパターンはまったく異なります。シングルトンパターンは、クラスローダーごとに特定のクラスのインスタンスが1つだけ作成されることを示しています。

Springシングルトンのスコープは、「Beanごとのコンテナごと」として記述されます。これは、Spring IoCコンテナーごとの単一オブジェクトインスタンスに対するBean定義の範囲です。 Springのデフォルトのスコープはシングルトンです。

デフォルトのスコープはシングルトンですが、<bean ../>要素のスコープ属性を指定することにより、Beanのスコープを変更できます。

<bean id=".." class=".." scope="prototype" />
54
user184794

最も単純な例を見てみましょう。アプリケーションがあり、デフォルトのクラスローダーを使用するだけです。何らかの理由で、アプリケーション内に複数のインスタンスを含めるべきではないと判断したクラスがあります。 (数人がアプリケーションの一部で作業するシナリオを考えてください)。

Springフレームワークを使用していない場合、Singletonパターンにより、アプリケーションにクラスのインスタンスが複数存在しないことが保証されます。これは、コンストラクタがプライベートであるため、「new」を実行してクラスのインスタンスをインスタンス化できないためです。クラスのインスタンスを取得する唯一の方法は、常に同じインスタンスを返すクラスの静的メソッド(通常「getInstance」と呼ばれる)を呼び出すことです。

アプリケーションでSpringフレームワークを使用していると言うと、クラスのインスタンスを取得する通常の方法(クラスのインスタンスを返す新しいメソッドまたは静的メソッド)に加えて、Springにあなたに取得することもできますそのクラスのインスタンスとSpringは、シングルトンパターンを使用してクラスを記述していなくても、そのクラスのインスタンスを要求するたびに常に同じインスタンスを返すようにします。つまり、クラスにパブリックコンストラクターがある場合でも、そのクラスのインスタンスを常にSpringに要求すると、Springはアプリケーションの有効期間中にそのコンストラクターを1回だけ呼び出します。

通常、Springを使用している場合、Springのみを使用してインスタンスを作成する必要があり、クラスのパブリックコンストラクターを使用できます。ただし、コンストラクタがプライベートでない場合、Springをバイパスすることにより、クラスの新しいインスタンスを直接作成することをだれも防ぐことはできません。

アプリケーションでSpringを使用し、Springでクラスをシングルトンとして定義した場合でも、クラスの単一インスタンスが本当に必要な場合、それを保証する唯一の方法は、Singletonパターンを使用してクラスを実装することです。これにより、Springを使用してインスタンスを取得するか、Springをバイパスするかにかかわらず、単一のインスタンスが存在することが保証されます。

19
inor

Springのシングルトンスコープは、このBeanがSpringによって1回だけインスタンス化されることを意味します。プロトタイプスコープ(毎回新しいインスタンス)、リクエストスコープ(リクエストごとに1回)、セッションスコープ(HTTPセッションごとに1回)とは対照的です。

シングルトンスコープは、技術的にシングルトンデザインパターンと関係があることに注目しています。 Beanをシングルトンスコープに配置するために、シングルトンとしてBeanを実装する必要はありません。

10
lexicore

「Beanごとのコンテナごと」を理解するのは難しいと思います。 「Bean IDごとに1つのBean」と言います。それを理解するための例を示します。 Beanクラスのサンプルがあります。次のように、Bean定義でこのクラスから2つのBeanを定義しました。

<bean id="id1" class="com.example.Sample" scope="singleton">
        <property name="name" value="James Bond 001"/>    
</bean>    
<bean id="id7" class="com.example.Sample" scope="singleton">
        <property name="name" value="James Bond 007"/>    
</bean>

したがって、ID「id1」のBeanを取得しようとすると、Springコンテナは1つのBeanを作成し、キャッシュして、id1で参照された同じBeanを返します。 id7で取得しようとすると、Sampleクラスから別のBeanが作成され、id7で参照するたびに同じBeanがキャッシュされて返されます。

これは、Singletonパターンでは起こりそうにありません。 Singltonパターンでは、クラスローダーごとに1つのオブジェクトが常に作成されます。しかし、春には同じクラスに対して多くのオブジェクトが作成されます。ただし、Springでは、同じIDに対して同じオブジェクトを返すシングルトンとしてスコープを作成します。 参照

4
Dexter

SpringのシングルトンBeanとシングルトンデザインパターンに基づくクラスはまったく異なります。

シングルトンパターンにより、SpringシングルトンBeanのスコープが「Beanごとのコンテナごと」として記述されるクラスローダーごとに、特定のクラスのインスタンスが1つだけ作成されることが保証されます。 Springのシングルトンスコープは、このBeanがSpringによって1回だけインスタンス化されることを意味します。 Springコンテナは、Beanを取得するための後続の呼び出しで同じインスタンスを何度も単に返すだけです。

2
JavaMave

2つの間には根本的な違いがあります。シングルトンデザインパターンの場合、クラスローダーごとにクラスのインスタンスが1つだけ作成されますが、IoCコンテナーごとに指定されたIDの1つの共有Beanインスタンスが作成されるSpringシングルトンの場合はそうではありません。

たとえば、「SpringTest」という名前のクラスがあり、XMLファイルが次のようになっている場合:-

<bean id="test1" class="com.SpringTest" scope="singleton">
        --some properties here
</bean>    
<bean id="test2" class="com.SpringTest" scope="singleton">
        --some properties here   
</bean>

したがって、メインクラスでは、上記の2つの参照を確認すると、Springのドキュメントに従ってfalseが返されます。

Beanがシングルトンの場合、Beanの共有インスタンスは1つだけ管理され、そのBean定義に一致するIDを持つBeanのすべてのリクエストは、Springコンテナによってその特定のBeanインスタンスが返されます。

したがって、この場合のように、クラスは同じですが、提供したIDは異なるため、2つの異なるインスタンスが作成されます。

2
hhhakki

春の「シングルトン」は、Beanファクトリのgetインスタンスを使用してキャッシュします。どのシングルトンデザインパターンが厳密であるか、インスタンスは静的なgetメソッドからのみ取得でき、オブジェクトをパブリックにインスタンス化することはできません。

1
lwpro2

例:「Beanごとのコンテナごと」。

        <bean id="myBean" class="com.spring4hibernate4.TestBean">
            <constructor-arg name="i" value="1"></constructor-arg>
            <property name="name" value="1-name"></property>
        </bean>

        <bean id="testBean" class="com.spring4hibernate4.TestBean">
            <constructor-arg name="i" value="10"></constructor-arg>
            <property name="name" value="10-name"></property>
        </bean>
    </beans>



    public class Test {

        @SuppressWarnings("resource")
        public static void main(String[] args) {
            ApplicationContext ac = new ClassPathXmlApplicationContext("ws.xml");
            TestBean teatBean = (TestBean) ac.getBean("testBean");
            TestBean myBean1 = (TestBean) ac.getBean("myBean");
            System.out.println("a : " + teatBean.test + " : "   + teatBean.getName());
            teatBean.setName("a TEST BEAN 1");
            System.out.println("uPdate : " + teatBean.test + " : "  + teatBean.getName());
            System.out.println("a1 : " + myBean1.test + " : " + myBean1.getName());
            myBean1.setName(" a1 TEST BEAN 10");
            System.out.println("a1 update : " + teatBean.test + " : " + myBean1.getName());
        }
    }

public class TestBean {
    public int test = 0;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private String name = "default";

    public TestBean(int i) {
        test += i;
    }
}

Java SINGLETON:

public class Singleton {
    private static Singleton singleton = new Singleton();
    private int i = 0;

    private Singleton() {
    }

    public static Singleton returnSingleton() {

        return singleton;
    }

    public void increment() {
        i++;
    }

    public int getInt() {
        return i;
    }
}

public static void main(String[] args) {
        System.out.println("Test");

        Singleton sin1 = Singleton.returnSingleton();
        sin1.increment();
        System.out.println(sin1.getInt());
        Singleton sin2 = Singleton.returnSingleton();
        System.out.println("Test");
        sin1.increment();
        System.out.println(sin1.getInt());
    }
1
Hariprasad

Spring Singleton Beanは、「Beanごとのコンテナごと」として記述されます。 Springのシングルトンスコープは、同じメモリ位置にある同じオブジェクトが同じBean IDに返されることを意味します。同じクラスの異なるIDの複数のBeanを作成すると、コンテナは異なるオブジェクトを異なるIDに返します。これは、キーがBean IDであり、値が1つのスプリングコンテナ内のBeanオブジェクトであるキー値マッピングのようなものです。シングルトンパターンでは、クラスローダーごとに特定のクラスのインスタンスが1つだけ作成されることが保証されます。

1