1.5.Beanスコープ
Bean定義を作成するとき、我々はスキーマで定義されたBeanクラスの実用的な例を作成するためのレシピを作成します。レシピのアイデアは、それがそのクラスを意味するので、あなたはレシピビーン定義から多くのインスタンスを作成することができ、非常に重要です。
春のフレームワークは、春のApplicationContext Web環境でのみ利用可能な4つの6つのスコープをサポートしています。また、カスタムスコープを作成することができます。
スコープ | 説明 |
---|---|
シングルトン | (デフォルト)は、単一のオブジェクトのインスタンスとして各ビーンスプリングIoCコンテナのための単一の定義を規定します。 |
プロトタイプ | 個々の豆は、オブジェクトインスタンスの任意の数として定義されるスコープ。 |
リクエスト | 定義された範囲は、単一のHTTPリクエストの個々のBean寿命として定義されます。つまり、各HTTPリクエストは、単一Bean定義の後ろに作成されたBeanインスタンスを持っています。春のApplicationContext Web環境でのみ使用可能です。 |
セッション | HTTPセッションの定義された単一のBeanの範囲は、ライフサイクルとして定義されます。春のApplicationContext Web環境でのみ使用可能です。 |
応用 | ServletContextスコープ個々のBeanは、ライフサイクルを定義しました。春のApplicationContext Web環境でのみ使用可能です。 |
WebSocketを | 個々のBeanはのWebSocketは、ライフサイクルを定義したスコープ。春のApplicationContext Web環境でのみ使用可能です。 |
春3.0以降では、スレッドが利用可能スコープが、デフォルトで登録されていません。詳細については、マニュアルを参照してくださいSimpleThreadScope
。
典型的には、プロトタイプの範囲は、すべてのステートフルBean、ステートレスBeanの単一の実施形態の範囲に使用されるべきです。
春ブーツは、XML設定ファイル中にコードを読んで:
lambda$loadBeanDefinitionsFromImportedResources$0:379, ConfigurationClassBeanDefinitionReader (org.springframework.context.annotation)
accept:-1, 351656492 (org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader$$Lambda$167)
forEach:684, LinkedHashMap (java.util)
loadBeanDefinitionsFromImportedResources:346, ConfigurationClassBeanDefinitionReader (org.springframework.context.annotation)
loadBeanDefinitionsForConfigurationClass:147, ConfigurationClassBeanDefinitionReader (org.springframework.context.annotation)
loadBeanDefinitions:120, ConfigurationClassBeanDefinitionReader (org.springframework.context.annotation)
processConfigBeanDefinitions:337, ConfigurationClassPostProcessor (org.springframework.context.annotation)
postProcessBeanDefinitionRegistry:242, ConfigurationClassPostProcessor (org.springframework.context.annotation)
invokeBeanDefinitionRegistryPostProcessors:275, PostProcessorRegistrationDelegate (org.springframework.context.support)
invokeBeanFactoryPostProcessors:95, PostProcessorRegistrationDelegate (org.springframework.context.support)
invokeBeanFactoryPostProcessors:706, AbstractApplicationContext (org.springframework.context.support)
refresh:532, AbstractApplicationContext (org.springframework.context.support)
refresh:747, SpringApplication (org.springframework.boot)
refreshContext:397, SpringApplication (org.springframework.boot)
run:315, SpringApplication (org.springframework.boot)
run:1226, SpringApplication (org.springframework.boot)
run:1215, SpringApplication (org.springframework.boot)
main:13, Application (study.hwj.spring)
1.5.2。プロトタイプスコープ
他のスコープと比較して、春はプロトタイプビーンのライフサイクル全体を管理することはできません。容器の例は、さらに記録することなく、クライアントへのプロトタイプの例が与えられているプロトタイプオブジェクトを、配置または組み立て。このように、すべてのオブジェクトに適用範囲を考慮しない場合、一方では、ライフサイクル・コールバック・メソッドの初期化と呼ばれていますが、試作品の場合には、設定されたコールバックのライフサイクルの破壊を呼び出すことはありません。クライアントコードは、プロトタイプオブジェクトのスコープをクリアし、高価なリソースは豆が持つプロトタイプリリースしなければなりません。、豆をクリーンアップする必要性への参照を含むカスタムビーンポストプロセッサを、使用してみていたプロトタイプの作用の下でリソースを解放するためのSpring Beanのコンテナを作るために。[???どのように破壊法に対処するビーンポストプロセッサのプロトタイプを作成]
プロトタイプスコープのJavaビーンの点で特定の態様では、ばね容器は、役割new
別のオペレータ。この時点を越えてすべてのライフサイクル管理は、クライアントによって処理されなければなりません。
1.5.3。シングルトンビーンビーンはプロトタイプの依存関係を持っています
あなたはスコープシングルトン、プロトタイプビーンビーンへの依存性を持っている場合は、その依存性がインスタンス化で解決されていますのでご注意ください。あなたは、単一の実施形態豆の範囲内と範囲Beanをプロトタイプ場合したがって、それは新しいプロトタイプBeanをインスタンス化し、その後、豆シングルトンの依存関係に注入します。プロトタイプの例としては、豆の単一の範囲に供給された実施形態の一例に過ぎません。
ただし、実行時にシングルトンスコープのBeanは豆のプロトタイプスコープの新しいインスタンスを取得するために繰り返したいとします。コンテナは、春の豆シングルトンインスタンス化され、解析され、その依存性注入されると、注入が一度だけ発生するので、あなたは、あなたの豆単一の実施形態に豆の依存性注入の範囲をプロトタイプすることはできません。あなたは、実行時に豆の新しいプロトタイプの複数のインスタンスが必要な場合は、参照方法注射を。
1.5.4。リクエスト、セッション、アプリケーション、および範囲のWebSocket
あなたは、Webベースの春のApplicationContextの実装を使用する場合にのみ(例えばXmlWebApplicationContext)、、 、、request
および利用可能スコープ。あなたは、従来のスコープのSpring IoCコンテナ(例えばClassPathXmlApplicationContext)と一緒にこれらを使用する場合、それは未知の豆のスコープをスローします。session
application
websocket
IllegalStateException
リクエスト・スコープ
<bean id="loginAction" class="com.something.LoginAction" scope="request"/>
@RequestScope
@Component
public class LoginAction {
// ...
}
セッションスコープ
<bean id="userPreferences" class="com.something.UserPreferences" scope="session"/>
@SessionScope
@Component
public class UserPreferences {
// ...
}
アプリケーションスコープ
<bean id="appPreferences" class="com.something.AppPreferences" scope="application"/>
@ApplicationScope
@Component
public class AppPreferences {
// ...
}
Springコンテナは、Webアプリケーション全体のAppPreferencesビーンappPreferences Bean定義を使用して、新しいインスタンスを作成します。言い換えるとのServletContextレベルで、appPreferences豆範囲、および通常のServletContext属性として格納されています。これは、やや似シングルトンのSpring Beanですが、二つの重要な違いがあります。それは、それぞれあるServletContext
春のApplicationContextの代わりに、(任意のWebアプリケーションでより多くの必要があるかもしれません)シングルトン、そして実際には、すべてのしたがってのServletContextのプロパティを見ることができるように、それは、開示されています。
依存関係として豆範囲
豆は、リクエスト、セッション、およびカスタムのスコープを使用する必要性のレベルのためのスコープ<aop:scoped-proxy/>
の要素を。
<bean id="userPreferences" class="com.something.UserPreferences" scope="session">
<aop:scoped-proxy/>
</bean>
<bean id="userManager" class="com.something.UserManager">
<property name="userPreferences" ref="userPreferences"/>
</bean>
また、の範囲内とすることができるsingleton
豆の間の使用<aop:scoped-proxy/>
、基準シリアライズ中間プロキシによって、ターゲットは単一の実施形態豆デシリアライズに回復することができます。
でprototype
豆の宣言の範囲<aop:scoped-proxy/>
、プロキシ呼の各方法のシェアは、新しいターゲット・インスタンスが作成されると、ターゲット・インスタンスへの呼び出しを転送します。
同様に、エージェントの範囲が短いスコープからのBeanのライフサイクル・アクセスを確保するための唯一の方法ではありません。あなたはまた、注入点を(即ち、フィールドまたはコンストラクタパラメータ設定部又は自動組立)宣言ObjectFactory<MyTargetBean>
ことにより、各時間を可能には、インスタンスを保持し、または別々に格納する必要なしに、現在の要求のインスタンスを取得するためのgetObject()呼び出しを必要としました。
拡張変形として、あなたは宣言することができObjectProvider<MyTargetBean>
、それは、以下を含むいくつかの追加の変種、へのアクセスを提供し、getIfAvailable
そしてgetIfUnique
。
これは、呼び出されたProvider
JSR-330の変異体を、それぞれ取得しようとProvider<MyTargetBean>
声明し、対応するget()
呼び出しで使用します。JSR-330、全体の詳細については、を参照してくださいここに。
作成するプロキシの種類を選択します
Springコンテナが使用されているデフォルトでは、<aop:scoped-proxy/>
ラベルされた豆のプロキシ要素を作成するときに、エージェントがベースCGLIBクラスを作成しました。
インターセプトメソッド呼び出しにCGLIB唯一の公共機関!このような薬剤の非パブリックメソッドを呼び出さないでください。彼らは、ターゲットオブジェクトの実際の範囲に委任されていません。
また、ユーザーが指定できる<aop:scoped-proxy/>
の要素proxy-target-class
のプロパティ値をfalse
、Springコンテナは、このようなスコープBeanのエージェントベースの標準のJDKインタフェースを作成するように構成しました。あなたは、アプリケーションのクラスパスのライブラリは、このような他のプロキシエージェントベースのJDKインタフェースによって影響を受ける可能性があるという手段を使用する必要はありません。しかし、これはまた、豆の範囲は、少なくとも一つのインターフェースを実装する必要があり、およびBeanがすべての共同編集者に注入されたスコープは、そのインターフェースのうちの1つを介してBeanを参照しなければならないことを意味します。
1.5.5。カスタムスコープ
豆スコープ機構は拡張可能です。独自のスコープを定義し、さらに既存の範囲を再定義し、後者は悪い習慣と考えられているが、あなたは、組み込みのスコープを上書きすることはできませんsingleton
とprototype
。
カスタムスコープを作成します。
私たちは、実装する必要がorg.springframework.beans.factory.config.Scope
インターフェイスを。
カスタムスコープを使用します
org.springframework.beans.factory.config.ConfigurableBeanFactory#registerScope
Scope threadScope = new SimpleThreadScope();
beanFactory.registerScope("thread", threadScope);
カスタム使ってScope
実装を、あなたはプログラム登録の範囲に限定されるものではありません。あなたも作ることができ用CustomScopeConfigurer
、次の例のように、宣言的スコープにクラスが登録します:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="thread">
<bean class="org.springframework.context.support.SimpleThreadScope"/>
</entry>
</map>
</property>
</bean>
<bean id="thing2" class="x.y.Thing2" scope="thread">
<property name="name" value="Rick"/>
<aop:scoped-proxy/>
</bean>
<bean id="thing1" class="x.y.Thing1">
<property name="thing2" ref="thing2"/>
</bean>
</beans>
あなたがFactoryBeanの実装を配置すると<aop:scoped-proxy/>
、範囲は工場出荷時には豆そのものではなく、からであるgetObject()
オブジェクトが返さ。