コンテナーの概要
org.springframework.context.ApplicationContext
インターフェースは Spring IoC コンテナーを表し、Bean のインスタンス化、構成、アセンブルを担当します。コンテナーは、構成メタデータを読み取ることで、インスタンス化、構成、アセンブルするコンポーネントに関する指示を取得します。構成メタデータは、アノテーション付きコンポーネントクラス、ファクトリメソッドを含む構成クラス、または外部 XML ファイルや Groovy スクリプトとして表すことができます。どちらの形式でも、アプリケーションとそれらのコンポーネント間の豊富な相互依存関係を構成できます。
ApplicationContext
インターフェースのいくつかの実装は、コア Spring の一部です。スタンドアロンアプリケーションでは、AnnotationConfigApplicationContext
(Javadoc) または ClassPathXmlApplicationContext
(Javadoc) のインスタンスを作成するのが一般的です。
ほとんどのアプリケーションシナリオでは、Spring IoC コンテナーの 1 つ以上のインスタンスを作成するために明示的なユーザーコードは必要ありません。例: 単純な Web アプリケーションシナリオでは、アプリケーションの web.xml
ファイル内の単純な定型 Web 記述子 XML で十分です (Web アプリケーション用の便利な ApplicationContext インスタンス化を参照)。Spring Boot シナリオでは、一般的なセットアップ規則に基づいて、アプリケーションコンテキストが暗黙的にブートストラップされます。
次の図は、Spring の機能の概要を示しています。アプリケーションクラスは構成メタデータと組み合わされ、ApplicationContext
が作成および初期化された後、完全に構成された実行可能なシステムまたはアプリケーションができます。
構成メタデータ
上の図が示すように、Spring IoC コンテナーは構成メタデータの形式を使用します。この構成メタデータは、アプリケーション開発者が Spring コンテナーにアプリケーション内のコンポーネントをインスタンス化、構成、アセンブルするように指示する方法を表します。
Spring IoC コンテナー自体は、この構成メタデータが実際に書き込まれる形式から完全に切り離されています。最近では、多くの開発者が Spring アプリケーションに Java ベースの構成を選択しています。
アノテーションベースの構成 : アプリケーションのコンポーネントクラスでアノテーションベースの構成メタデータを使用して Bean を定義します。
Java ベースの構成 : Java ベースの構成クラスを使用して、アプリケーションクラスの外部に Bean を定義します。これらの機能を使用するには、
@Configuration
(Javadoc) 、@Bean
(Javadoc) 、@Import
(Javadoc) 、@DependsOn
(Javadoc) アノテーションを参照してください。
Spring 構成は、コンテナーが管理する必要がある少なくとも 1 つの、通常は複数の Bean 定義で構成されます。Java 構成では通常、@Configuration
クラス内の @Bean
アノテーション付きメソッドが使用され、各メソッドは 1 つの Bean 定義に対応します。
これらの Bean 定義は、アプリケーションを構成する実際のオブジェクトに対応しています。通常、サービスレイヤーオブジェクト、リポジトリやデータアクセスオブジェクト (DAO) などの永続レイヤーオブジェクト、Web コントローラーなどのプレゼンテーションオブジェクト、JPA EntityManagerFactory
などのインフラストラクチャオブジェクト、JMS キューなどを定義します。通常、ドメインオブジェクトを作成してロードするのはリポジトリとビジネスロジックの責任であるため、通常、コンテナー内にきめ細かなドメインオブジェクトを構成することはありません。
外部構成 DSL としての XML
XML ベースの構成メタデータは、これらの Bean を最上位の <beans/>
要素内の <bean/>
要素として構成します。次の例は、XML ベースの構成メタデータの基本構造を示しています。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="..." class="..."> (1) (2)
<!-- collaborators and configuration for this bean go here -->
</bean>
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here -->
</beans>
1 | id 属性は、個々の Bean 定義を識別する文字列です。 |
2 | class 属性は、Bean の型を定義し、完全修飾クラス名を使用します。 |
id
属性の値を使用して、コラボレートするオブジェクトを参照できます。コラボレーションオブジェクトを参照するための XML は、この例には示されていません。詳細については、依存関係を参照してください。
コンテナーをインスタンス化するには、コンテナーがローカルファイルシステム、Java CLASSPATH
などのさまざまな外部リソースから構成メタデータをロードできるようにする、XML リソースファイルへの場所パスまたはパスを ClassPathXmlApplicationContext
コンストラクターに提供する必要があります。
Java
Kotlin
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
val context = ClassPathXmlApplicationContext("services.xml", "daos.xml")
Spring の IoC コンテナーについて学習した後は、URI 構文で定義された場所から InputStream を読み取るための便利なメカニズムを提供する Spring の |
次の例は、サービスレイヤーオブジェクト (services.xml)
構成ファイルを示しています。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- services -->
<bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
<property name="accountDao" ref="accountDao"/>
<property name="itemDao" ref="itemDao"/>
<!-- additional collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions for services go here -->
</beans>
次の例は、データアクセスオブジェクト daos.xml
ファイルを示しています。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="accountDao"
class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao">
<!-- additional collaborators and configuration for this bean go here -->
</bean>
<bean id="itemDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao">
<!-- additional collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions for data access objects go here -->
</beans>
前の例では、サービスレイヤーは PetStoreServiceImpl
クラスと、型 JpaAccountDao
および JpaItemDao
の 2 つのデータアクセスオブジェクト(JPA オブジェクトリレーショナルマッピング標準に基づく)で構成されています。property name
エレメントは JavaBean プロパティの名前を参照し、ref
エレメントは別の Bean 定義の名前を参照します。id
要素と ref
要素の間のこのリンケージは、コラボレーションするオブジェクト間の依存関係を表します。オブジェクトの依存関係の構成の詳細については、依存関係を参照してください。
XML ベースの構成メタデータの作成
Bean 定義が複数の XML ファイルにまたがっていると便利です。多くの場合、個々の XML 構成ファイルは、アーキテクチャ内の論理層またはモジュールを表します。
ClassPathXmlApplicationContext
コンストラクターを使用して、XML フラグメントから Bean 定義をロードできます。このコンストラクターは、前のセクションで示したように、複数の Resource
の場所を取ります。または、<import/>
要素の 1 つ以上の出現を使用して、別のファイルから Bean 定義をロードします。次の例は、その方法を示しています。
<beans>
<import resource="services.xml"/>
<import resource="resources/messageSource.xml"/>
<import resource="/resources/themeSource.xml"/>
<bean id="bean1" class="..."/>
<bean id="bean2" class="..."/>
</beans>
前の例では、外部 Bean 定義は、services.xml
、messageSource.xml
、themeSource.xml
の 3 つのファイルからロードされます。すべてのロケーションパスは、インポートを実行する定義ファイルに関連しているため、services.xml
はインポートを実行するファイルと同じディレクトリまたはクラスパスの場所にある必要があり、messageSource.xml
および themeSource.xml
はインポートファイルの場所の resources
の場所にある必要があります。ご覧のとおり、先頭のスラッシュは無視されます。ただし、これらのパスは相対的なものであるため、スラッシュをまったく使用しない方が適切です。Spring スキーマによれば、インポートされるファイルの内容は、最上位の <beans/>
要素を含め、有効な XML Bean 定義である必要があります。
相対パス "../" を使用して親ディレクトリのファイルを参照することは可能ですが、推奨されません。これを行うと、現在のアプリケーションの外部にあるファイルに依存関係が作成されます。特に、この参照は 相対パスの代わりに、たとえば |
ネームスペース自体がインポートディレクティブ機能を提供します。context
および util
名前空間など、Spring が提供する XML 名前空間の選択では、プレーンな Bean 定義を超えるさらなる構成機能を利用できます。
Groovy Bean 定義 DSL
外部化された設定メタデータのさらなる例として、Grails フレームワークで知られているように、Bean 定義は Spring の Groovy Bean Definition DSL でも表現できます。通常、このような設定は、次の例に示す構造を持つ ".groovy" ファイルに存在します。
beans {
dataSource(BasicDataSource) {
driverClassName = "org.hsqldb.jdbcDriver"
url = "jdbc:hsqldb:mem:grailsDB"
username = "sa"
password = ""
settings = [mynew:"setting"]
}
sessionFactory(SessionFactory) {
dataSource = dataSource
}
myService(MyService) {
nestedBean = { AnotherBean bean ->
dataSource = dataSource
}
}
}
この構成スタイルは、XML Bean 定義とほぼ同等であり、Spring の XML 構成名前空間もサポートしています。また、importBeans
ディレクティブを介して XML Bean 定義ファイルをインポートすることもできます。
コンテナーの使用
ApplicationContext
は、さまざまな Bean とその依存関係のレジストリを維持することができる高度なファクトリのインターフェースです。メソッド T getBean(String name, Class<T> requiredType)
を使用すると、Bean のインスタンスを取得できます。
ApplicationContext
では、次の例に示すように、Bean 定義を読み取ってそれらにアクセスできます。
Java
Kotlin
// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService.class);
// use configured instance
List<String> userList = service.getUsernameList();
import org.springframework.beans.factory.getBean
// create and configure beans
val context = ClassPathXmlApplicationContext("services.xml", "daos.xml")
// retrieve configured instance
val service = context.getBean<PetStoreService>("petStore")
// use configured instance
var userList = service.getUsernameList()
Groovy 構成では、ブートストラップは非常に似ています。Groovy 対応の異なるコンテキスト実装クラスがあります(ただし、XML Bean 定義も理解します)。次の例は、Groovy 構成を示しています。
Java
Kotlin
ApplicationContext context = new GenericGroovyApplicationContext("services.groovy", "daos.groovy");
val context = GenericGroovyApplicationContext("services.groovy", "daos.groovy")
最も柔軟なバリアントは、次の例に示すように、リーダーデリゲートと組み合わせた GenericApplicationContext
です。たとえば、XML ファイルの XmlBeanDefinitionReader
です。
Java
Kotlin
GenericApplicationContext context = new GenericApplicationContext();
new XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml");
context.refresh();
val context = GenericApplicationContext()
XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml")
context.refresh()
次の例に示すように、Groovy ファイルに GroovyBeanDefinitionReader
を使用することもできます。
Java
Kotlin
GenericApplicationContext context = new GenericApplicationContext();
new GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy", "daos.groovy");
context.refresh();
val context = GenericApplicationContext()
GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy", "daos.groovy")
context.refresh()
同じリーダーデリゲートを同じ ApplicationContext
で組み合わせて、さまざまな構成ソースから Bean 定義を読み取ることができます。
その後、getBean
を使用して、Bean のインスタンスを取得できます。ApplicationContext
インターフェースには、Bean を取得するためのその他のメソッドがいくつかありますが、理想的には、アプリケーションコードで Bean を使用しないでください。実際、アプリケーションコードには getBean()
メソッドをまったく呼び出さないようにし、Spring API にまったく依存しないようにします。例: Spring の Web フレームワークとの統合は、コントローラーや JSF 管理の Bean などのさまざまな Web フレームワークコンポーネントへの依存性注入を提供し、メタデータ(オートワイヤーアノテーションなど)を通じて特定の Bean への依存性を宣言できます。