クラス ServiceLocatorFactoryBean

java.lang.ObjectSE
org.springframework.beans.factory.config.ServiceLocatorFactoryBean
実装されたすべてのインターフェース:
AwareBeanFactoryAwareFactoryBean<ObjectSE>InitializingBean

public class ServiceLocatorFactoryBean extends ObjectSE implements FactoryBean<ObjectSE>, BeanFactoryAware, InitializingBean
シグニチャー MyType xxx() または MyType xxx(MyIdType id) (通常は MyService getService() または MyService getService(String id))を持つ 1 つ以上のメソッドが必要なインターフェースを取り、そのインターフェースを実装する動的プロキシを作成して、基になる BeanFactory に委譲する FactoryBean 実装。

このようなサービスロケーターでは、適切なカスタムロケーターインターフェースを使用して、呼び出しコードを BeanFactory API から分離できます。これらは通常、 プロトタイプ Bean に使用されます。つまり、呼び出しごとに新しいインスタンスを返すことになっているファクトリメソッドに使用されます。クライアントは setter またはコンストラクターインジェクションを介してサービスロケーターへの参照を受け取り、必要に応じてロケーターのファクトリメソッドを呼び出すことができます。 シングルトン Bean の場合、ターゲット Bean の直接 setter またはコンストラクターインジェクションが推奨されます。

引数のないファクトリメソッド、または null の文字列 ID または空の文字列を持つ単一引数のファクトリメソッドの呼び出し時に、ファクトリ内の 1 つの Bean がファクトリメソッドの戻り値の型と一致する場合、Bean が返されます。NoSuchBeanDefinitionException がスローされます。

null 以外(および空ではない)の引数を使用して単一引数のファクトリメソッドを呼び出すと、プロキシは、渡された ID の文字列化されたバージョンを Bean 名として使用して、BeanFactory.getBean(String) 呼び出しの結果を返します。

ファクトリメソッドの引数は通常 String ですが、たとえば toString を介して文字列化された int またはカスタム列挙型にすることもできます。結果の文字列は、対応する Bean が Bean ファクトリで定義されている限り、そのまま Bean 名として使用できます。または、サービス ID と Bean 名の間のカスタムマッピングを定義できます。

例として、次のサービスロケータインターフェースを考えてみます。このインターフェースは Spring API に依存しないことに注意してください。

package a.b.c;

public interface ServiceFactory {

    public MyService getService();
}

XML ベースの BeanFactory のサンプル構成は次のようになります。

<beans>

   <!-- Prototype bean since we have state -->
   <bean id="myService" class="a.b.c.MyService" singleton="false"/>

   <!-- will lookup the above 'myService' bean by *TYPE* -->
   <bean id="myServiceFactory"
            class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
     <property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/>
   </bean>

   <bean id="clientBean" class="a.b.c.MyClientBean">
     <property name="myServiceFactory" ref="myServiceFactory"/>
   </bean>

</beans>

アテンダント MyClientBean クラスの実装は、次のようになります。

package a.b.c;

public class MyClientBean {

    private ServiceFactory myServiceFactory;

    // actual implementation provided by the Spring container
    public void setServiceFactory(ServiceFactory myServiceFactory) {
        this.myServiceFactory = myServiceFactory;
    }

    public void someBusinessMethod() {
        // get a 'fresh', brand new MyService instance
        MyService service = this.myServiceFactory.getService();
        // use the service object to effect the business logic...
    }
}

Bean を名前で検索する例として、次のサービスロケータインターフェースについて考えてみます。繰り返しますが、このインターフェースは Spring API に依存していません。

package a.b.c;

public interface ServiceFactory {

    public MyService getService (String serviceName);
}

XML ベースの BeanFactory のサンプル構成は次のようになります。

<beans>

   <!-- Prototype beans since we have state (both extend MyService) -->
   <bean id="specialService" class="a.b.c.SpecialService" singleton="false"/>
   <bean id="anotherService" class="a.b.c.AnotherService" singleton="false"/>

   <bean id="myServiceFactory"
            class="org.springframework.beans.factory.config.ServiceLocatorFactoryBean">
     <property name="serviceLocatorInterface" value="a.b.c.ServiceFactory"/>
   </bean>

   <bean id="clientBean" class="a.b.c.MyClientBean">
     <property name="myServiceFactory" ref="myServiceFactory"/>
   </bean>

</beans>

アテンダント MyClientBean クラスの実装は、次のようになります。

package a.b.c;

public class MyClientBean {

    private ServiceFactory myServiceFactory;

    // actual implementation provided by the Spring container
    public void setServiceFactory(ServiceFactory myServiceFactory) {
        this.myServiceFactory = myServiceFactory;
    }

    public void someBusinessMethod() {
        // get a 'fresh', brand new MyService instance
        MyService service = this.myServiceFactory.getService("specialService");
        // use the service object to effect the business logic...
    }

    public void anotherBusinessMethod() {
        // get a 'fresh', brand new MyService instance
        MyService service = this.myServiceFactory.getService("anotherService");
        // use the service object to effect the business logic...
    }
}

別のアプローチについては、ObjectFactoryCreatingFactoryBean を参照してください。

導入:
1.1.4
作成者:
Colin Sampaleanu, Juergen Hoeller
関連事項:
  • コンストラクターの詳細

    • ServiceLocatorFactoryBean

      public ServiceLocatorFactoryBean()
  • メソッドの詳細

    • setServiceLocatorInterface

      public void setServiceLocatorInterface(ClassSE<?> interfaceType)
      使用するサービスロケーターインターフェースを設定します。これには、シグニチャー MyType xxx() または MyType xxx(MyIdType id) (通常、MyService getService() または MyService getService(String id))を持つ 1 つ以上のメソッドが必要です。このようなメソッドのセマンティクスについては、class-level Javadoc を参照してください。
    • setServiceLocatorExceptionClass

      public void setServiceLocatorExceptionClass(ClassSE<? extends ExceptionSE> serviceLocatorExceptionClass)
      サービスの検索が失敗した場合にサービスロケータがスローする例外クラスを設定します。指定された例外クラスには、(String, Throwable)(Throwable)(String) のいずれかのパラメーター型のコンストラクターが必要です。

      指定しない場合、Spring の BeansException のサブクラス(NoSuchBeanDefinitionException など)がスローされます。それらがチェックされていないため、呼び出し元はそれらを処理する必要がないため、Spring 例外は、それらが一般的に処理されるだけである限り、スローされても許容されます。

      関連事項:
    • setServiceMappings

      public void setServiceMappings(PropertiesSE serviceMappings)
      サービス ID(サービスロケータに渡される)と Bean 名(Bean ファクトリ内)の間のマッピングを設定します。ここで定義されていないサービス ID は、そのまま Bean 名として扱われます。

      サービス ID キーとしての空の文字列は、null と空の文字列のマッピング、およびパラメーターのないファクトリメソッドの定義を定義します。定義されていない場合、一致する単一の Bean が Bean ファクトリから取得されます。

      パラメーター:
      serviceMappings - サービス ID とキーとしてのサービス ID を値としての Bean 名として、サービス ID と Bean 名の間のマッピング
    • setBeanFactory

      public void setBeanFactory(BeanFactory beanFactory) throws BeansException
      インターフェースからコピーされた説明: BeanFactoryAware
      所有ファクトリを Bean インスタンスに提供するコールバック。

      通常の Bean プロパティの設定後、ただし InitializingBean.afterPropertiesSet() またはカスタム init-method などの初期化コールバックの前に呼び出されます。

      次で指定:
      インターフェース BeanFactoryAwaresetBeanFactory 
      パラメーター:
      beanFactory - 所有 BeanFactory(非 null)。Bean は、ファクトリのメソッドをすぐに呼び出すことができます。
      例外:
      BeansException - 初期化エラーの場合
      関連事項:
    • afterPropertiesSet

      public void afterPropertiesSet()
      インターフェースからコピーされた説明: InitializingBean
      すべての Bean プロパティを設定し、BeanFactoryAwareApplicationContextAware などを満たした後、包含 BeanFactory によって呼び出されます。

      このメソッドにより、Bean インスタンスは、すべての Bean プロパティが設定されたときに、その全体的な構成の検証と最終的な初期化を実行できます。

      次で指定:
      インターフェース InitializingBeanafterPropertiesSet 
    • determineServiceLocatorExceptionConstructor

      protected ConstructorSE<ExceptionSE> determineServiceLocatorExceptionConstructor(ClassSE<? extends ExceptionSE> exceptionClass)
      指定されたサービスロケーター例外クラスに使用するコンストラクターを決定します。カスタムサービスロケーター例外の場合にのみ呼び出されます。

      デフォルトの実装では、パラメーター型 (String, Throwable) または (Throwable) または (String) のいずれかを持つコンストラクターを探します。

      パラメーター:
      exceptionClass - 例外クラス
      戻り値:
      使用するコンストラクター
      関連事項:
    • createServiceLocatorException

      protected ExceptionSE createServiceLocatorException(ConstructorSE<ExceptionSE> exceptionConstructor, BeansException cause)
      指定された原因に対してサービスロケータ例外を作成します。カスタムサービスロケーター例外の場合にのみ呼び出されます。

      デフォルトの実装では、メッセージと例外の引数のすべてのバリエーションを処理できます。

      パラメーター:
      exceptionConstructor - 使用するコンストラクター
      cause - サービス検索の失敗の原因
      戻り値:
      スローするサービスロケータ例外
      関連事項:
    • getObject

      @Nullable public ObjectSE getObject()
      インターフェースからコピーされた説明: FactoryBean
      このファクトリによって管理されるオブジェクトのインスタンス(おそらく共有または独立)を返します。

      BeanFactory と同様に、これにより、シングルトンとプロトタイプの両方のデザインパターンをサポートできます。

      この FactoryBean が呼び出し時にまだ完全に初期化されていない場合(たとえば、循環参照に関係しているため)、対応する FactoryBeanNotInitializedException をスローします。

      Spring 2.0 以降、FactoryBeans は null オブジェクトを返すことができます。ファクトリはこれを通常の値として使用します。この場合、FactoryBeanNotInitializedException はスローされません。FactoryBean の実装では、必要に応じて FactoryBeanNotInitializedException 自体をすぐにスローすることをお勧めします。

      次で指定:
      インターフェース FactoryBean<ObjectSE>getObject 
      戻り値:
      Bean のインスタンス (null にすることができます)
      関連事項:
    • getObjectType

      @Nullable public ClassSE<?> getObjectType()
      インターフェースからコピーされた説明: FactoryBean
      この FactoryBean が作成するオブジェクトの型、または事前に不明な場合は null を返します。

      これにより、たとえばオートワイヤーなどで、オブジェクトをインスタンス化せずに特定の型の Bean を確認できます。

      シングルトンオブジェクトを作成している実装の場合、このメソッドはシングルトンの作成を可能な限り回避しようとします。むしろ、事前に型を推定する必要があります。プロトタイプの場合、ここで意味のある型を返すこともお勧めします。

      このメソッドは、この FactoryBean が完全に初期化される前に呼び出すことができます。初期化中に作成された状態に依存しないでください。もちろん、利用可能な場合はそのような状態を引き続き使用できます。

      注意 : オートワイヤーは、ここで null を返す FactoryBeans を単に無視します。FactoryBean の現在の状態を使用して、このメソッドを適切に実装することを強くお勧めします。

      次で指定:
      インターフェース FactoryBean<ObjectSE>getObjectType 
      戻り値:
      この FactoryBean が作成するオブジェクトの型、または呼び出し時に不明な場合は null 
      関連事項:
    • isSingleton

      public boolean isSingleton()
      インターフェースからコピーされた説明: FactoryBean
      このファクトリによって管理されるオブジェクトはシングルトンですか? つまり、FactoryBean.getObject() は常に同じオブジェクト(キャッシュ可能な参照)を返しますか?

      注意 : FactoryBean がシングルトンオブジェクトを保持することを示す場合、getObject() から返されたオブジェクトは所有 BeanFactory によってキャッシュされる可能性があります。FactoryBean が常に同じ参照を公開しない限り、true を返さないでください。

      FactoryBean 自体のシングルトンステータスは、通常、所有する BeanFactory によって提供されます。通常、そこではシングルトンとして定義する必要があります。

      注意 false を返すこのメソッドは、返されるオブジェクトが独立したインスタンスであることを必ずしも示しません。拡張 SmartFactoryBean インターフェースの実装は、SmartFactoryBean.isPrototype() メソッドを通じて独立したインスタンスを明示的に示す場合があります。この拡張インターフェースを実装しないプレーンな FactoryBean 実装は、isSingleton() 実装が false を返す場合、常に独立したインスタンスを返すと単純に想定されます。

      FactoryBean は通常シングルトンインスタンスを管理するため、デフォルトの実装は true を返します。

      次で指定:
      インターフェース FactoryBean<ObjectSE>isSingleton 
      戻り値:
      公開されたオブジェクトがシングルトンかどうか
      関連事項: