大きな波が砂を洗い流し、通り過ぎないようにしたいだけです
まず、Spring Containerについての私の個人的な理解についてお話しします(Spring公式Webサイトのすべてのプロジェクトには、Spring Springframework、または略してSpring Frameworkと呼ばれるプロジェクトがあります)
Spring Frameworkは、管理のためにSpringに渡すオブジェクトを格納するために使用されるコンテナーであり、Beanと呼ばれます。
コアモジュールは主にIOCとAOP(Web、テストなど)に分けられます。
IOCは、制御の反転および依存性注入とも呼ばれます。主なアイデアはデカップリングです。制御の反転は主に、プログラマーが新しいキーワードを使用してオブジェクトを作成し、オブジェクト間の依存関係を維持する必要があることを意味します。IOCの後、このオブジェクトをコンテナーに渡すだけで済みます。オブジェクト間の依存関係を作成および維持するのに役立ちます。
また、アスペクト指向プログラミングであるAOPは、プロジェクト内のパブリックモジュールを分離し、単一のモジュールにカプセル化します。このモジュールはアスペクトと呼ばれ、思考の分離のために生まれました。
aopは2つの方法で使用します。1つはxmlファイルを介して構成されたSpringaopで、もう1つはアノテーション@Aspectによって開かれます。
接続ポイント(式の実行、内部など)、カットポイント、通知(前、後、サラウンド、例外)、およびウィービングが必要です。
違いは、春のaopが実行時に動的に織り込まれることです。アスペクトはコンパイル時に静的に織り込まれます。どちらが個人的な好みに依存します
次に、AOPはIOCに依存しているため、IOCとAOPは2つの部分に分かれています(公式Webサイトは分離されています)。春豆のライフサイクルにはAOPの分析が伴うため、AOPはIOCの一部であると言えます(たとえば、最初のステップは次のとおりです。BeanPostProcessorのポストプロセッサを使用して、後の拡張に備えるためにプロキシする必要のあるオブジェクトのコレクションを埋めます。
最初に紹介したいのはBeanDefinitionオブジェクトです。Springの最終的な目標はJavaオブジェクトを変換することです---> BeanDefinition ---> Spring Bean
したがって、BeanDefinitionオブジェクトとその属性およびサブクラスは非常に重要です。春の公式サイトからこの写真をもう一度紹介してください
JavaオブジェクトはSpringコンテナを介してメタ属性を埋め、BeanDefinitionオブジェクトになります。ライフサイクル全体の後、Javaオブジェクトは使用するSpringBeanになります。プロセスと実装ではそれを行う必要はありません。
導入された2番目のポイントは、Springコンテナの拡張ポイントです。
拡張ポイントは次のとおりです
InitializingBean Spring Bean、ライフサイクルコールバックインターフェイスの1つであるSpring Web MVCは、このインターフェイスを実装するためにMapプロパティを初期化して入力します
SmartLifecycleSpringコンテナの初期化を完了するためのコールバックインターフェイスの1つ
ImportSelector Spring Bootの自動構成(Spring以外の自動アセンブリ)は、このインターフェースを実装します
ImportBeanDefinitionRegistrar MyBatisはSpringを統合して、このインターフェースのMapperScannerプロパティをスキャンするプロセスを実現します->プロキシオブジェクト-> Spring Bean
BeanFactoryPostProcessorBeanFactoryポストプロセッサ
BeanDefinitionRegistryPostProcessorは、BeanFactoryPostProcessorBeanFactoryファクトリポストプロセッサを拡張します
ConfigurationClassPostProcessorはBeanDefinitionRegistryPostProcessorを実装しますBeanFactoryファクトリポストプロセッサ組み込みのみの実装クラス
次に、ソースコード内のこれら3つのクラス(実装クラス)の実行タイミングを確認します。
new AnnotationConfigApplicationContext(AppConfig.class); this();//第一步 初始化 beanFactory 工厂 register(annotatedClasses); // 注册配置类 refresh(); // 如下
//准备工作包括设置启动时间,是否激活标识位,初始化属性源(property,source)配置 prepareRefresh(); //获取到 DefaultListableBeanFactory 对象 //已经注册过了 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //传入 beanFactory 调用处理器对Bean工厂做一些标准的配置 prepareBeanFactory(beanFactory); //空方法 postProcessBeanFactory(beanFactory); //执行自定义的BeanFactoryProcessor和内置的BeanFactoryProcessor // 完成扫描和解析 object -- > beanDefinition invokeBeanFactoryPostProcessors(beanFactory);//开始执行BeanFactory的后置处理器扩展点(策略模式) registerBeanPostProcessors(beanFactory);//开始执行BeanFactory 的后置处理器 initMessageSource(); initApplicationEventMulticaster(); onRefresh(); registerListeners(); //实例化所有的非懒加载单例 //bean生命周期 finishBeanFactoryInitialization(beanFactory); finishRefresh();
invokeBeanFactoryPostProcessors(beanFactory);
このインターフェースを実装するBeanDefinitionRegistryPostProcessorBeanFactoryのポストプロセッサの実行タイミング
1.最初に、BeanDefinitionRegistryPostProcessorおよびPriorityOrderedのインターフェースを実装するBeanFactoryのポストプロセッサーを実行します。
2.次に、BeanDefinitionRegistryPostProcessorおよびOrderedインターフェースを実装するBeanFactoryのポストプロセッサーを実行します。
3.最後に、BeanDefinitionRegistryPostProcessorのインターフェースを実装するBeanFactoryのポストプロセッサーを実行します。
BeanFactoryPostProcessorの実装タイミングこのインターフェースを実装するBeanFactoryのポストプロセッサ
4.最初に、BeanFactoryPostProcessorおよびPriorityOrderedインターフェースを実装するBeanFactoryのポストプロセッサーを実行します。
5.次に、BeanFactoryPostProcessorおよびOrderedインターフェースを実装するBeanFactoryのポストプロセッサーを実行します。
6.最後に、BeanFactoryPostProcessorインターフェースを実装するBeanFactoryのポストプロセッサーを実行します。
これらのBeanFactoryポストプロセッサを実行する場合、Springは主に親と子のBeanDefinitionのマージを完了するために、Beanポストプロセッサも実行するため、最初に導入したポイントは非常に重要です。
ConfigurationClassPostProcessorはBeanDefinitionRegistryPostProcessorを実装しますSpringは何をしますか?
2番目のスキャンを完了して、構成クラス@Import @PropertySource @ ComponentScans @ Beanに含まれるすべてのアノテーションを解析します。
そして、ImportSelectorインターフェースとImportBeanDefinitionRegistrarインターフェースを実装するクラス
BeanDefinitionにカプセル化され、BeanDefinitionMapに登録されます。
ConfigurationClassPostProcessorはBeanFactoryPostProcessorポストプロセッサを実装しますSpringは何をしましたか
主に構成クラスのCGLIB拡張を完了するために、以下を見てみましょう。
@ComponentScan("org.springframework.test2") @Configuration public class AppConfig { @Bean public B b(){ System.out.println("===b==="); return new B(); } @Bean public A a(){ System.out.println("===a==="); b(); return new A(); }
}
アノテーション@Configurationがaとbを1回だけ出力し、bを2回出力しないのはなぜですか。
オブジェクトaとオブジェクトbはどちらもシングルトンですが、なぜ2回初期化されるのですか?
追加されたアノテーション@Configurationは、ConfigurationClassPostProcessorクラスによって解析され、CGLIBプロキシが実行されます。
しかし、なぜbはCGLIB(春の循環依存原理)の後に一度だけ初期化されるのですか?
registerBeanPostProcessors(beanFactory);
このインターフェースを実装するBeanPostProcessorBeanのポストプロセッサーの実行タイミングには、Beanのライフサイクルが伴います。
1.最初に、BeanPostProcessorおよびPriorityOrderedインターフェースを実装するBeanのポストプロセッサーを追加します。
2.BeanPostProcessorおよびOrderedインターフェースを実装するBeanのポストプロセッサーを追加します
3.最後に、BeanPostProcessorインターフェースを実装するBeanのポストプロセッサーを追加します。
Beanのポストプロセッサ実行タイミング
1.インスタンス化されているBeanをプロキシする必要があるかどうかを判断し、必要に応じて、それをコレクションに追加して空を返します
InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation {return null}
2.推定工法
SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors {return null}
spring-ioc-inferredコンストラクター-手動アセンブリ spring-ioc-inferredコンストラクター-自動アセンブリ
3.親と子のBeanDefinitionをマージします
MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition
4.循環依存、ファクトリの公開、およびファクトリを介したBeanインスタンスの取得(ファクトリを公開する理由は、プロキシオブジェクトの属性をアセンブルするためです)SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference
5.属性インジェクション、現在のオブジェクトが属性インジェクションを許可するかどうかを決定します(デフォルトはtrue)InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
6. Javaイントロスペクションメカニズムに基づくJavaリフレクションメカニズム(インジェクションモデルの1つ)に基づく属性インジェクション手動インジェクション@Autowiredおよび@Resource自動インジェクション
ソースコード@Autowiredの@Autowiredと@Resourceの検索メソッドは、最初にタイプに従って検索し、見つかったタイプをコレクションに入れてから、コレクション内の名前で照合します。その逆も同様です。@ Resource
@Autowiredと@Resourceが自動インジェクションではない理由をご覧ください
7. Awareインターフェースを実装し、BeanPostProcessorのBeforeメソッドを自分で実装します
BeanPostProcessor#postProcessBeforeInitialization
8.動的プロキシプロキシ、およびBeanPostProcessorのAfterメソッドの独自の実装
BeanPostProcessor#postProcessAfterInitialization
Beanライフサイクルコールバックを実行する方法は3つあります
まず、コールバックを初期化します。実行の順序は、3つのタイプすべてに存在できます。注釈>インターフェース> xml
最初のxmlベースの<beaninit-method = "">
2番目のタイプは、インターフェースに基づいてInitializingBeanを実装します
3番目はアノテーション@PostConstructに基づいています
同様にコールバックを破棄します
<bean destroy-method = "">
DestroyBeanはDisposableBeanを実装します
@PreDestroy
Springコンテナのライフサイクルコールバックを実行する
SmartLifecycleインターフェースを実装するクラスとLifecycleインターフェースを実装するクラス
インターフェースライフサイクル{
void start();
void stop();
ブールisRunning();
}
インターフェースSmartLifecycle {
isAutoStartup();
void stop(Runnable callback);
int getPhase();
}
これで、SpringBeanのライフサイクルは終了しました。Springコンテナの初期化が完了しました。
要約すると、2つの部分があります
最初の部分BeanFactoryPostProcessorBeanFactoryのポストプロセッサは、Springコンテナの初期化の半分を完了します
BeanPostProcessorの2番目の部分Beanポストプロセッサは、Springコンテナの初期化とBeanのライフサイクルの残りの半分を完了します。