それは非常に簡単です:
_@Inject
private Provider<ProductService> productService;
_
ProductサービスはproductService.get()
を介して利用でき、.get()
は呼び出しごとにSpringコンテキストからインスタンスを解決します。
しかし、いつそれを使用する必要がありますか?そしてどこに?
私の主な使用例は非常に単純です。循環依存関係を取得すると、プロバイダーは実行時に依存関係を解決するのに役立ちます。しかし、循環依存関係が原因でコンテキストを作成できない場合にスローすると、少しランダムに見えます。
プロバイダーの使用に関する既知のパターンはありますか?
このインターフェイスは、プロトタイプインスタンスを探すときにクライアントコードでBeanFactory.getBean()
呼び出しを回避するために通常使用されるorg.springframework.beans.factory.ObjectFactory<T>
と同等です。 ObjectFactoryCreatingFactoryBean
をソースとするプロトタイプBeanを取得するためにBeanFactory
とともによく使用されます。
ObjectFactoryCreatingFactoryBean
javadocsの例:
<beans>
<!-- Prototype bean since we have state -->
<bean id="myService" class="a.b.c.MyService" scope="prototype"/>
<bean id="myServiceFactory"
class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
<property name="targetBeanName"><idref local="myService"/></property>
</bean>
<bean id="clientBean" class="a.b.c.MyClientBean">
<property name="myServiceFactory" ref="myServiceFactory"/>
</bean>
</beans>
Providers
を使用すると、代わりにProviderCreatingFactoryBean
を使用できます。
同じ問題を解決する他のオプション(構成ではなく継承を使用)は、 lookup method injection です。
Cdiでは、プロバイダーはより狭いスコープのオブジェクトをより広いスコープのBeanに注入するために使用されます。たとえば、セッションスコープのBeanがリクエストスコープのオブジェクトへのアクセスを必要とする場合、プロバイダーとリクエストで実行されているメソッドを注入します、provider.get()
を呼び出して、適切な要求スコープオブジェクトへのローカル変数参照を取得します。
次の場合:
@RequestScoped
public class Bean1 {
void doSomething();
}
以下は、セッションの最初のリクエストに関連付けられたBean1インスタンスを使用して、どのリクエストがBean2.doSomething()を呼び出しているかに関係なく、Bean2を使用します。
@SessionScoped
public class Bean2 {
@Inject Bean1 bean;
public void doSomething() {
bean.doSomething();
}
}
以下は、現在Bean3.doSomething()を呼び出している特定のリクエストに関連付けられたBeanのインスタンス、つまりリクエストごとに異なるBeanを使用します。
@SessionScoped
public class Bean3 {
@Inject Provider<Bean1> bean;
public void doSomething() {
bean.get().doSomething();
}
}