5

特定のメソッドが実行されるたびに別のBeanの新しいインスタンス(Xと呼びましょう)を必要とするシングルトンのSpring Beanがあります(シングルトンのままである必要があります)。

これまで、次のアプローチを見てきました。

  • newを使用してXを作成するだけです。これはしばらくは機能していましたが、X用のSpring AOP機能が必要になりました。結果として得られるインスタンスはSpringで管理されていないため、これは機能しなくなりました。

  • FactoryBeanを依存関係と見なしましたが、FactoryBeanから取得するXインスタンスは1つだけであり、最初のインスタンスには適合しません。

  • 現在の計画では、SpringコンテキストでXを手動で検索し、プロトタイプの依存関係を使用してXを宣言します。これはうまくいくはずですが、本当に醜いと思います。

=> Beanにファクトリを注入して、適切であると判断したときにいつでもファクトリメソッドを呼び出して、Springマネージドインスタンスをそこから取得できるようにするにはどうすればよいですか。

4

2 に答える 2

12

このようなシナリオで選択する手段は、ルックアップメソッドインジェクションと呼ばれます。つまり、これはBeanメソッドの呼び出しのアプローチを使用して、新しいBeanインスタンスが作成されます。まず、依存関係インスタンスを最終的に提供する抽象メソッドを使用してクラスを作成します。

abstract class MyClient implements Client {

  void businessMethod(…) {

    Dependency dependency = getDependencyInstance();
    …
  }

  abstract Dependency getDependencyInstance();
}

次に、依存関係のプロトタイプBean定義を構成します。

<bean id="dependency" class="….DependencyImpl" scope="prototype" />

lookup-methodまた、要素を使用して各メソッド呼び出しの依存関係の新しいインスタンスを常に取得するクライアントは次のようになります。

<bean class="….MyClient">
  <lookup-method name="getDependencyInstance" bean="dependency" />
</bean>

これにより、CGLibプロキシが作成され、Beanの名前とを参照してaによってサポートされるMyClientメソッド宣言が検索されます。メソッドを呼び出すたびに、Beanルックアップがトリガーされ、プロトタイプ構成済みBeanの新しいインスタンスが返されます。getDependencyInstance(…)TargetSourceBeanFactory

于 2012-10-23T08:30:46.327 に答える
2

ファクトリBeanに問題は見られないので、次のようにします。

import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;

@Component
public class X {
    public static class XFactory implements FactoryBean<X> {

        @Override
        public X getObject() throws Exception {
            return new X();
        }

        @Override
        public Class<?> getObjectType() {
            return X.class;
        }

        @Override
        public boolean isSingleton() {
            return false;
        }       
    }
}

このファクトリービーンを注入します。

それ以外の場合は、XBeanのスコープを設定できます

@Scope(proxyMode=ScopedProxyMode.TARGET_CLASS, value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)

Springが常に新しいインスタンスをシングルトンに返すプロキシを作成するように、デフォルト以外のプロキシモードを使用する必要があります。

XML構成を使用している場合は、次のようにします。

<bean id="x" class="X" scope="prototype">
<aop:scoped-proxy>
</bean>

楽しむ。

編集:

@Componentを介してファクトリに注釈を付ける場合(上記で追加しました)、#isSingletonでfalseを返し、Xを2回返さないように注意して、@Autowiredを使用してファクトリBeanをシングルトンに注入できます。

そうでなければ私はちょうどチェックしました

import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;

@Component
@Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class X {
}

期待どおりに動作します。

編集2:

ファクトリBeanを注入せずに依存関係を注入したい場合は、ファクトリのスコープをプロトタイプ化できます(@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS、value = "prototype"))が、Xよりも毎回新しいファクトリが作成されます。おそらくあなたが望むものではないが関与しています。

工場自体を注入したくない場合は、Oliversルックアップメソッドを使用します。

于 2012-10-23T07:02:15.127 に答える