序文
あなたと私がここで出会ったのは、すべてステレオタイプのエッセイのせいです。
1年後にはインターンシップを探す予定なので、事前に知識を蓄えておきたいし、面接の際に拷問されて死ぬことのないように祈りたいです。この一連の記事では、Spring フレームワークを探索した私の経験と知識を共有します。
この時点では逃げられないのでガンガンやりましょう。
この記事で検討する質問は次のとおりです。
- BeanFactory とアプリケーションの違いは何ですか?
- BeanFactoryとアプリケーションの実装?
1. BeanFactory と ApplicationContext の違いは何ですか?
1. それらは何ですか?
名前が示すように、BeanFactory はBean のインスタンス化、構成、管理を主な役割とするBean 処理ファクトリーであり、遅延初期化 (Bean 取得時のインスタンス化をサポート) をサポートし、最も単純なコンテナー機能を提供します。
ApplicationContext-----アプリケーション コンテキストは、BeanFactory から派生した BeanFactory のサブインターフェイスであり、Bean 定義とオブジェクト間のコラボレーション関係を維持し、よりエンタープライズ レベルの機能を提供できる高レベルのインターフェイスです。
どちらもSpringフレームワークのコンテナであり、ApplicationContextは複数のインタフェースを継承しており、BeanFactoryに比べてより実用的な機能が拡張されており、Springの中核となるコンテナとして欠かせない機能を担っている。
まず、2 つの間の継承関係を確認します。
ApplicationtonContext は BeanFactory を間接的に継承します
同時に、BeanFactory は単純な関数のコンテナーとして、2 つのマニフェストを持ちます。
まず、SpringApplication が生成する ConfigurableApplicationContext の実装クラスに AbstractApplicationContext の getBean メソッドがあることが分かります。
2 番目に、DefaultListableBeanFactorys はBeanFactoryを実装します。ApplicationContext プロパティとして、タイプ ConcurrentHashMap のプロパティがすべてのシングルトン Bean を保存するように設定されます。
結果をたどる
編集
2. 違い
BeanFactory は、古くからある Factory として、IOC (制御の反転: オブジェクトの制御をプログラム コード自体から外部コンテナに移すことを逆に行います。オブジェクトの作成、初期化、破棄はコンテナに引き継がれます。) とDI (依存性注入) 機能はサポートされますが、AOP、Web アプリケーション、その他の機能などの Spring プラグインはサポートできません。
BeanFactory を使用して Bean を取得する場合、コンテナーをインスタンス化するだけであり、コンテナー内の Bean はインスタンス化されません。getBean を実行すると、Bean オブジェクトはリアルタイムでインスタンス化されます。これは一般に遅延読み込みとして知られています。
BeanFactory インターフェースの一般的な実装クラスには、DefaultListableBeanFactoryおよびXmlBeanFactoryなどがあります。
ApplicationContext は、BeanFactory のすべての機能を提供することに加えて、AOP (アスペクト指向プログラミング)、イベント発行、国際化、リソース読み込み、Bean ライフサイクル管理、セキュリティなど、よりエンタープライズレベルの機能も提供します。
- EnvironmentCapable は、Environment の環境を統合します
- メッセージソースの国際化
- ResourcePatternResolver は、ワイルドカードを使用して Resource リソースのセットを取得します
- ApplicationEventPublisher イベントの公開と監視
イベントの発行と監視
ApplicationContext を使用して Bean を取得すると、必要な Bean が事前に作成されます。
2. BeanFactory と ApplicationContext の実装?
BeanFactoryの実装
BeanFactory オブジェクトを作成 --> Bean を定義 (クラス、スコープ、初期化、破棄) --> Bean を登録
——> 共通プロセッサを追加し、BeanFactory のコンパレータを設定します (@Bean、@Configuration などのアノテーションを解析するために使用されます) —> ポストプロセッサを機能させる —> ポストプロセッサを補足します
注:一般的に使用されるプロセッサの最初の追加は、BeanFactory 内の単なる Bean である BeanFactory にいくつかのポストプロセッサを追加するだけであり、接続は確立されていません。2 つ目は、BeanFactoryとポスト間の接続を追加することです。-processor BeanFactory の各 Bean が作成された後に、どのポストプロセッサが必要かを通知します。
スクス
コードをコピーする
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); //定义 AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Config.class). setScope("singleton").getBeanDefinition(); //注册 beanFactory.registerBeanDefinition("config",beanDefinition); //为BeanFactory提供一些常用处理器 //此外还设置了比较器 AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory); //根据一个类型获取多个Bean,使其工作,扩展 beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().stream().forEach(beanFactoryPostProcessor -> { System.out.println(beanFactoryPostProcessor); beanFactoryPostProcessor.postProcessBeanFactory(beanFactory); }); System.out.println("<<<<<<<<<<<<<<<<<<<<<<<<<"); //Bean后处理器,对bean生命周期各个阶段提供扩展,告诉bean工厂,创建bean实例的时候需要哪些后处理器 //internalCommonAnnotationProcessor Resource处理器 beanFactory.getBeansOfType(BeanPostProcessor.class). values().stream().sorted(beanFactory.getDependencyComparator()) .forEach(beanPostProcessor -> { System.out.println("beanFactory.getBeansOfType数据如下:"+beanPostProcessor); beanFactory.addBeanPostProcessor(beanPostProcessor); }); for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) { System.out.println(beanDefinitionName); } //预先创建好Bean,Bean的创建是懒加载 beanFactory.preInstantiateSingletons();
ポストプロセッサの実装
@Autowried は型に従って自動的にアセンブルされます。インターフェイスに 2 つの実装クラスがあり、それらが両方ともコンテナーに注入される場合、@Autowried を使用してこのインターフェイスに依存関係を注入するとどうなりますか?
答えは例外を報告することです
スレッド「メイン」での例外 org.springframework.beans.factory.UnsatisfiedDependencyException
BeanFactory は、このインターフェースにどの実装クラスを注入すべきかを知らないためです。解決策は、@Qualifier を使用するか、対応する実装クラスの名前と一致するようにインターフェイス変数の名前を変更することで、インジェクションも成功する可能性があります。
@Resource のデフォルトも変数名に基づいていますが、名前が追加されている場合は名前の優先順位が高くなります。
このときクラス内のプロパティに対して依存性注入を行っているとして、@Resourceと@Autowriedを同時に追加するとどうなるでしょうか?
答えは注射が成功したことです
これらには優先関係があり、@Autowried の優先順位が @Resource よりも高いため、@Autowried は直接処理され、@Resource は無視されます。プロセス中にプロセッサを追加するとコンパレータが設定されるのですが、ソースコードを読むと設定値と比較されることが分かります。
これは@Resourceのプロセッサであり、その中のsetOrderのパラメータで数値を示し、優先度を決定します。
ApplicationContextの実装
Spring は、さまざまなアプリケーション シナリオで選択できるさまざまなタイプのコンテナ実装を提供します。
- ClassPathXmlApplicationContext (クラスパスから XML 構成ファイルをロードします)
- AnnotationConfigApplicationContext (Java アノテーションを使用して構成)
- FileSystemXmlApplicationContext (ファイル システムから XML 構成ファイルをロードします)
- XmlWebApplicationContext ( Web アプリケーションの下の 1 つ以上の XML 構成ファイルからコンテキスト定義をロードします。XML 構成モードに適用されます)
同時に、BeanFactory と比較して、補足的な操作を追加するポストプロセッサーを節約します。