私はSpring Frameworkを初めて使用します。SpringMVCを評価して、今後の企業プロジェクトで使用できるようにするために、Spring Frameworkをいじくり回し、いくつかのサンプルアプリをまとめています。これまでのところ、私はSpring MVCで見たものが本当に好きで、非常に使いやすいようで、ユニットテストに非常に適したクラスを書くことを奨励しています。
ちょうど演習として、サンプル/テストプロジェクトの1つのメインメソッドを書いています。不明な点の1つは、BeanFactory
とApplicationContext
の正確な違いです。どの条件で使用するのが適切ですか。
ApplicationContext
はBeanFactory
を拡張することを理解していますが、単純なmainメソッドを作成しているだけの場合、ApplicationContext
が提供する追加機能が必要ですか?そして、ApplicationContext
はどのような追加機能を提供しますか?
「main()メソッドでどちらを使用すべきか」という答えに加えて、そのようなシナリオでどの実装を使用すべきかについて、標準やガイドラインはありますか? main()メソッドは、XML形式になるようにBean /アプリケーション構成に依存するように作成する必要がありますか?それは安全な仮定ですか、またはユーザーを特定の何かにロックしていますか?
そして、この答えはWeb環境で変わりますか?私のクラスのいずれかがSpringを認識する必要がある場合、ApplicationContext
が必要になる可能性が高いですか?
助けてくれてありがとう。これらの質問の多くはおそらくリファレンスマニュアルで回答されていることを知っていますが、細かい歯の櫛でマニュアルを読むことなく、これら2つのインターフェイスとそれぞれの長所/短所の明確な内訳を見つけるのに苦労しています。
春のドキュメントはこれについて素晴らしいです: .8.1。BeanFactoryまたはApplicationContext? 。それらには比較の表があり、スニペットを投稿します:
Bean Factory
アプリケーションコンテキスト
そのため、アプリケーションコンテキスト側で提示されるポイントのいずれかが必要な場合は、ApplicationContextを使用する必要があります。
私にとって、BeanFactory
よりもApplicationContext
を選択する主な違いは、ApplicationContext
がすべてのBeanを事前インスタンス化することです。 From theSpringdocs ::
Springは、Beanが実際に作成されたときに、プロパティを設定し、可能な限り遅く依存関係を解決します。つまり、正しくロードされたSpringコンテナは、オブジェクトまたはその依存関係の作成に問題がある場合、オブジェクトを要求すると、後で例外を生成できることを意味します。たとえば、Beanはプロパティの欠落または無効の結果として例外をスローします。一部の構成問題の潜在的な遅延可視性が、デフォルトでApplicationContext実装がシングルトンBeanを事前インスタンス化する理由です。これらのBeanを実際に必要になる前に作成するための事前の時間とメモリを犠牲にして、後でではなくApplicationContextの作成時に構成の問題を発見します。このデフォルトの動作をオーバーライドして、シングルトンBeanが事前インスタンス化されるのではなく、遅延初期化されるようにすることができます。
これを考慮して、最初に統合/パフォーマンステストで使用するBeanFactory
を選択しました。分離されたBeanをテストするためにアプリケーション全体をロードしたくなかったからです。しかし-そして私が間違っていれば誰かが私を修正します-BeanFactory
はclasspath
XML構成をサポートしません。したがって、BeanFactory
とApplicationContext
はそれぞれ、私が望んでいた重要な機能を提供しますが、両方とも提供しませんでした。
私が知る限り、デフォルトのインスタンス化動作のオーバーライドに関するドキュメント内の注意は構成内で行われ、Beanごとに行われるため、XMLファイルに「lazy-init」属性を設定することはできません。テスト用と展開用にバージョンを維持し続けました。
私がやったことは、ClassPathXmlApplicationContext
を拡張して、次のようなテストで使用するために遅延的にBeanをロードすることでした:
public class LazyLoadingXmlApplicationContext extends ClassPathXmlApplicationContext {
public LazyLoadingXmlApplicationContext(String[] configLocations) {
super(configLocations);
}
/**
* Upon loading bean definitions, force beans to be lazy-initialized.
* @see org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.xml.XmlBeanDefinitionReader)
*/
@Override
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
super.loadBeanDefinitions(reader);
for (String name: reader.getBeanFactory().getBeanDefinitionNames()) {
AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) reader.getBeanFactory().getBeanDefinition(name);
beanDefinition.setLazyInit(true);
}
}
}
Springは、2種類のIOCコンテナを提供します。1つは
XMLBeanFactory
、もう1つはApplicationContext
です。
+---------------------------------------+-----------------+--------------------------------+
| | BeanFactory | ApplicationContext |
+---------------------------------------+-----------------+--------------------------------+
| Annotation support | No | Yes |
| BeanPostProcessor Registration | Manual | Automatic |
| implementation | XMLBeanFactory | ClassPath/FileSystem/WebXmlApplicationContext|
| internationalization | No | Yes |
| Enterprise services | No | Yes |
| ApplicationEvent publication | No | Yes |
+---------------------------------------+-----------------+--------------------------------+
FileSystemXmlApplicationContext
完全パスを介してロードされたBean。ClassPathXmlApplicationContext
CLASSPATHを介してロードされたBeanXMLWebApplicationContext
およびAnnotationConfigWebApplicationContext
Bean。AnnotationConfigApplicationContext
注釈ベースの設定からSpring Beanをロードしています。例:
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeansConfiguration.class);
ApplicationContext
は、web.xml
で定義されたContextLoaderListener
またはContextLoaderServlet
およびstruts-config.xml
で定義されたContextLoaderPlugin
によって初期化されたコンテナーです。注:XmlBeanFactory
は、 非推奨 Spring 3.1以降、DefaultListableBeanFactory
およびXmlBeanDefinitionReader
を優先します。
Miguel Pingが答えたものに追加するために、ここに ドキュメントの別のセクション があり、これも同様に答えます:
短いバージョン:ApplicationContextを使用しない理由が特にない限り、ApplicationContextを使用します。上記の推奨事項の「しかし、なぜ」についてもう少し深さを探しているあなたのために、読み続けてください。
(この質問を読むかもしれない将来の春の初心者のためにこれを投稿する)
ApplicationContext
はBeanFactory
よりも好ましい方法です
新しいSpringバージョンでは、BeanFactory
はApplicationContext
に置き換えられます。ただし、下位互換性のためにBeanFactory
はまだ存在します
ApplicationContext extends BeanFactory
には次の利点があります既に誰かが言ったようなモバイル環境にいる場合を除き、常にApplicationContextを使用する方が良いと思います。 ApplicationContextにはより多くの機能があり、Spring構成ファイルを単純化するのに役立つRequiredAnnotationBeanPostProcessor、AutowiredAnnotationBeanPostProcessor、およびCommonAnnotationBeanPostProcessorなどのPostProcessorを間違いなく使用します。また、Beanで@ Required、@ PostConstruct、@ Resourceなどの注釈を使用できます。
ApplicationContextが提供するすべてのものを使用しなくても、とにかくそれを使用することをお勧めします。その後、メッセージやポストプロセッサなどのリソースのもの、またはトランザクションアドバイスなどを追加する他のスキーマを使用することにした場合、 ApplicationContextが既にあり、コードを変更する必要はありません。
スタンドアロンアプリを作成する場合は、ClassPathXmlApplicationContextを使用してメインメソッドにApplicationContextを読み込み、メインBeanを取得してそのrun()(または任意のメソッド)を呼び出してアプリを起動します。 Webアプリを作成する場合は、web.xmlのContextLoaderListenerを使用してApplicationContextを作成し、JSP、JSF、JSTL、Struts、Tapestryなどを使用しているかどうかに関係なく、ServletContextから後で取得できるようにします。
また、複数のSpring構成ファイルを使用でき、コンストラクター内のすべてのファイルをリストする(またはContextLoaderListenerのcontext-paramにリストする)ことによってApplicationContextを作成できること、またはインポート文。 <import resource = "otherfile.xml" />を使用して、Spring構成ファイルを別のSpring構成ファイルにインポートできます。これは、mainメソッドでApplicationContextをプログラムで作成し、1つのSpring構成ファイルのみをロードする場合に非常に便利です。
ApplicationContext: Spring構成ファイルで構成されたSpring Beanをロードし、Container StartsとしてSpring Beanのライフサイクルを管理します。getBean( "springbeanref")まで待機しませんが呼び出されます。
BeanFactory Spring構成ファイルで構成されたSpring Beanをロードし、getBean( "springbeanref")を呼び出すときにSpring Beanのライフサイクルを管理します。 getBean( "springbeanref") Spring Beanのライフサイクルの開始時。
ほとんどの場合、モバイルアプリケーションのようにリソースを保存する必要がない限り、ApplicationContextが優先されます。
XML形式に依存するかどうかはわかりませんが、ApplicationContextの最も一般的な実装は、ClassPathXmlApplicationContext、XmlWebApplicationContext、FileSystemXmlApplicationContextなどのXML実装であると確信しています。これらは私が今まで使った唯一の3つです。
Webアプリを開発している場合、XmlWebApplicationContextを使用する必要があると言っても安全です。
BeanにSpringを認識させたい場合は、BeanにBeanFactoryAwareまたはApplicationContextAware、あるいはその両方を実装させることができるため、BeanFactoryまたはApplicationContextを使用して、実装するインターフェースを選択できます。
BeanFactoryとApplicationContextの違いは次のとおりです。
BeanFactory:を使用
BeanFactory beanfactory = new XMLBeanFactory(new FileSystemResource("spring.xml")); Triangle triangle =(Triangle)beanFactory.getBean("triangle");
ApplicationContext:を使用
ApplicationContext context = new ClassPathXMLApplicationContext("spring.xml") Triangle triangle =(Triangle)beanFactory.getBean("triangle");
BeanFactoryおよびApplicationContextは両方とも、SpringからBeanを取得する方法ですIOCコンテナーですが、まだいくつかの違いがあります。
BeanFactoryは、多数のBeanをインスタンス化、構成、および管理する実際のコンテナです。これらのBeanは通常、相互に連携しているため、相互に依存関係があります。これらの依存関係は、BeanFactoryが使用する構成データに反映されます。
BeanFactoryおよびApplicationContextは両方ともJavaインターフェースであり、ApplicationContextはBeanFactoryを拡張します。どちらもXML構成ファイルを使用した構成です。つまり、BeanFactoryはcontrol(IoC)およびDependency Injection(DI)機能の基本的な反転を提供し、ApplicationContextはadvanced機能を提供します。
BeanFactoryは、インターフェース "org.springframework.beans.factory"で表されます。ここで、BeanFactoryには、複数の実装があります。
ClassPathResource resource = new ClassPathResource("appConfig.xml");
XmlBeanFactory factory = new XmlBeanFactory(resource);
差
BeanFactory呼び出し時にBeanをインスタンス化しますgetBean()メソッドは、コンテナが起動されたときにApplicationContextがシングルトンBeanをインスタンス化します。getBean()が呼び出されるのを待ちません。
BeanFactoryは国際化のサポートを提供しませんが、ApplicationContextは国際化のサポートを提供します。
BeanFactory vs ApplicationContextのもう1つの違いは、リスナーとして登録されているBeanにイベントを公開する機能です。
BeanFactoryインターフェイスの一般的な実装の1つはXMLBeanFactoryですが、ApplicationContextインターフェイスの一般的な実装の1つはClassPathXmlApplicationContextです。
自動配線を使用し、BeanFactoryを使用している場合、AutoWiredBeanPostProcessorを登録する必要がありますApplicationContextを使用している場合、XMLで設定できるAPIを使用します。要約するとBeanFactoryはテストおよび本番以外の使用には問題ありませんが、ApplicationContextはより機能豊富なコンテナ実装であり、BeanFactoryよりも優先されるべきです。
BeanFactoryデフォルトでサポートLazyロードおよびApplicationContextデフォルトでサポートAggresiveロード。
a。 Beanファクトリとアプリケーションコンテキストの違いの1つは、コンテナの起動時にApplicationContextがシングルトンBeanをインスタンス化するのに対してgetBean()メソッドを呼び出すときにのみBeanをインスタンス化することです。getBeanの呼び出しを待機しません。
b。
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
または
ApplicationContext context = new ClassPathXmlApplicationContext{"spring_dao.xml","spring_service.xml};
プロジェクトの要件に応じて、1つ以上のxmlファイルを使用できます。ここでは、2つのxmlファイルを使用しています。つまり、1つはdaoクラスの他のサービスクラスの設定詳細用です。ここで、ClassPathXmlApplicationContextはApplicationContextの子です。
c。 BeanFactoryコンテナは基本的なコンテナであり、オブジェクトの作成と依存関係の注入のみが可能です。ただし、セキュリティ、トランザクション、メッセージングなどの他のサービスを添付して、ApplicationContext Containerを使用する必要があるすべてのサービスを提供することはできません。
d。 BeanFactoryは国際化、つまりi18nのサポートを提供しませんが、ApplicationContextはそれをサポートします。
e。 BeanFactory ContainerはAutoScanning(アノテーションベースの依存性注入をサポート)の機能をサポートしていませんが、ApplicationContext Containerはサポートしています。
f。 Beanfactory Containerは、リクエスト時までBeanオブジェクトを作成しません。 Beanfactory Containerは、Beanを遅延的にロードすることを意味します。 ApplicationContext Containerは、ロード時のみにシングルトンBeanのオブジェクトを作成します。それは、早期の読み込みがあることを意味します。
g。 Beanfactory Containerは、Beanの2つのスコープ(シングルトンとプロトタイプ)のみをサポートします。ただし、ApplicationContext ContainerはすべてのBeanスコープをサポートします。
基本的に、2つの方法でスプリングコンテナオブジェクトを作成できます。
両方ともインターフェースです
実装クラスを使用して、スプリングコンテナのオブジェクトを作成できます
違いに来る
BeanFactory
注釈ベースの依存性注入はサポートしていません。
I18Nをサポートしていません
デフォルトでは、遅延読み込みをサポートしています
複数の構成ファイルに構成することはできません。
例:BeanFactory context = new XmlBeanFactory(new Resource( "applicationContext.xml"));
ApplicationContext
注釈ベースの依存性注入をサポートします。@ Autowired、@ PreDestroy
I18Nをサポート
そのデフォルトでは、Aggresiveロードをサポートしています。
複数の構成ファイルを構成できます。
例:
ApplicationContext context = new ClasspathXmlApplicationContext( "applicationContext.xml");
リアルタイムシナリオでは、Spring IOC Coreコンテナ(BeanFactory)とAdvanced J2EEコンテナ(ApplicationContext)の違いは次のとおりです。
BeanFactoryは、.getBean()メソッドを呼び出すときにのみspring.xmlファイル(<bean></bean>
)に記述されているBean(つまり、POJOクラス)のオブジェクトを作成しますが、ApplicationContextはすべてのBean(<bean></bean>
のスコープの場合、 spring.xmlファイル自体の読み込み中にspring.xmlで設定された「プロトタイプ」として明示的に言及されていません。
BeanFactory:(遅延コンテナは、ユーザー/メインクラスから明示的に呼び出す場合にのみBeanのオブジェクトを作成するため)
/*
* Using core Container - Lazy container - Because it creates the bean objects On-Demand
*/
//creating a resource
Resource r = (Resource) new ClassPathResource("com.spring.resources/spring.xml");
//creating BeanFactory
BeanFactory factory=new XmlBeanFactory(r);
//Getting the bean for the POJO class "HelloWorld.Java"
HelloWorld worldObj1 = (HelloWorld) factory.getBean("test");
ApplicationContext:(spring.xmlファイル自体のロード中にすべてのシングルトンBeanのオブジェクトを作成するための熱心なコンテナー)
ApplicationContext context = new ClassPathXmlApplicationContext("com/ioc/constructorDI/resources/spring.xml");
技術的には、リアルタイムアプリケーションでは、アプリケーションがサーバー自体で開始されている間にBeanオブジェクトが作成されるため、ApplicationContextの使用をお勧めします。これにより、オブジェクトは既に応答可能になっているため、ユーザー要求の応答時間が短縮されます。
ApplicationContextはBeanFactoryの兄であり、これはBeanFactoryが提供するすべてのものに加えて他の多くのものを提供します。
標準のorg.springframework.beans.factory.BeanFactoryライフサイクル機能に加えて、ApplicationContext実装はApplicationContextAware Bean、ResourceLoaderAware、ApplicationEventPublisherAware、およびMessageSourceAware Beanを検出して呼び出します。
Spring Docsのこのドキュメントを参照してください。
5.15.1 BeanFactoryまたはApplicationContext?
そうしない理由がない限り、ApplicationContextを使用します。
ApplicationContextにはBeanFactoryのすべての機能が含まれているため、一般的にはBeanFactoryよりも推奨されます。ただし、メモリ消費が重要で、数キロバイト余分に変化するアプレットなどのいくつかの状況を除きます。ただし、ほとんどの典型的なエンタープライズアプリケーションおよびシステムでは、ApplicationContextを使用する必要があります。 Spring 2.0以降では、BeanPostProcessor拡張ポイントを多用しています(プロキシ処理などを行うため)。プレーンBeanFactoryのみを使用する場合、トランザクションやAOPなどのかなりの量のサポートは有効になりません。少なくともあなたの側でいくつかの追加のステップが必要です。実際には構成に問題はないため、この状況は混乱を招く可能性があります。
要約すれば:
ApplicationContextには、BeanFactoryのすべての機能が含まれています。通常、前者を使用することをお勧めします。
モバイルアプリケーションなど、メモリの消費が重要になる可能性のある限られた状況があります。
そのシナリオでは、より軽量なBeanFactoryを使用することを正当化できます。ただし、ほとんどのエンタープライズアプリケーションでは、ApplicationContextを使用します。
詳細については、私のブログ投稿を参照してください。
SpringでのBeanFactoryとApplicationContextの違い–基本からのJava springブログ
singletonおよびPrototype Beanスコープのみをサポートするため、非WebアプリケーションにBeanFactoryを使用してください。
ApplicationContextコンテナはすべてのBeanスコープをサポートしているため、Webアプリケーションに使用する必要があります。
Spring 3以降、ファクトリを作成する場合は、 @configuration
アノテーションを適切な @scope
と組み合わせて使用することもできます。
@Configuration
public class MyFactory {
@Bean
@Scope("prototype")
public MyClass create() {
return new MyClass();
}
}
@ComponentScan
アノテーションまたはxml構成を使用して、Springコンテナでファクトリを表示する必要があります