當前位置:
                    首頁 >
                            前端技术
>                            javascript
>内容正文                
                        
                    javascript
Spring容器初始化和bean创建过程
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                Spring容器初始化和bean创建过程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                文章目錄
- Spring容器初始化過程(注解)
- 1.this() 初始化bean讀取器和掃描器
- 2. register(annotatedClasses)
- 3 refresh()刷新上下文
 
 
前言:一直想詳細了解下Spring容器初始化和bean創建過程,今天抽空通過翻閱各種資料,對Spring容器初始化和bean的創建有了大概了解。
Spring容器初始化過程(注解)
以AnnotationConfigApplicationContext為例:
 查看繼承圖:
 從AnnotationConfigApplicationContext源碼分析
AnnotationConfigApplicationContex主要代碼
public AnnotationConfigApplicationContext(Class... annotatedClasses) {this(); //2.注冊bean配置類this.register(annotatedClasses); //3.刷新上下文this.refresh();}1.this() 初始化bean讀取器和掃描器
public AnnotationConfigApplicationContext() {//在IOC容器中初始化一個 注解bean讀取器AnnotatedBeanDefinitionReaderthis.reader = new AnnotatedBeanDefinitionReader(this);//在IOC容器中初始化一個 按類路徑掃描注解bean的 掃描器this.scanner = new ClassPathBeanDefinitionScanner(this);}2. register(annotatedClasses)
注冊bean配置類, AnnotationConfigApplicationContext容器通過AnnotatedBeanDefinitionReader的registerBean方法實現注解bean的讀取,具體源碼如下:AnnotationConfigApplicationContext.java中register方法
public void registerBean(Class<?> annotatedClass) {doRegisterBean(annotatedClass, null, null, null);}<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {//將Bean配置類信息轉成容器中AnnotatedGenericBeanDefinition數據結構, AnnotatedGenericBeanDefinition繼承//自BeanDefinition作用是定義一個bean的數據結構,下面的getMetadata可以獲取到該bean上的注解信息AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);//@Conditional裝配條件判斷是否需要跳過注冊if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}abd.setInstanceSupplier(instanceSupplier);//解析bean作用域(單例或者原型),如果有@Scope注解,則解析@Scope,沒有則默認為singletonScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);//作用域寫回BeanDefinition數據結構, abd中缺損的情況下為空,將默認值singleton重新賦值到abdabd.setScope(scopeMetadata.getScopeName());//生成bean配置類beanNameString beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));//通用注解解析到abd結構中,主要是處理Lazy, primary DependsOn, Role ,Description這五個注解AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);if (qualifiers != null) {for (Class<? extends Annotation> qualifier : qualifiers) {//如果配置@Primary注解,則設置當前Bean為自動裝配autowire時首選beanif (Primary.class == qualifier) {abd.setPrimary(true);}//設置當前bean為延遲加載else if (Lazy.class == qualifier) {abd.setLazyInit(true);}//其他注解,則添加到abd結構中else {abd.addQualifier(new AutowireCandidateQualifier(qualifier));}}}for (BeanDefinitionCustomizer customizer : definitionCustomizers) {customizer.customize(abd);} //根據beanName和bean定義信息封裝一個BeanDefinitionHolder,其實就是一個 beanname和BeanDefinition的映射 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);//創建代理對象 借助AnnotationConfigUtils工具類解析通用注解definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);// new ConcurrentHashMap<String, BeanDefinition>(256);用于保存注bean定義信息(beanname 和 beandefine映射)注冊到IOC容器中BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);}目的:完成bean配置類本身的解析和注冊。將其以鍵值對的形式保存到IOC容器中。
3 refresh()刷新上下文
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 1.刷新前的預處理prepareRefresh();// 2.獲取刷新后的內部Bean工廠ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//3.BeanFactory的預準備工作prepareBeanFactory(beanFactory);try {// BeanFactory準備工作完成后,可以做一些后置處理工作//4.空方法,用于在容器的子類中擴展postProcessBeanFactory(beanFactory);// 5. 執行BeanFactoryPostProcessor的方法,BeanFactory的后置處理器//在BeanFactory標準初始化之后執行的invokeBeanFactoryPostProcessors(beanFactory);// 6. 注冊BeanPostProcessor(Bean的后置處理器),用于攔截bean創建過程registerBeanPostProcessors(beanFactory);// 7. 初始化MessageSource組件(做國際化功能;消息綁定,消息解析).initMessageSource();// 8. 初始化事件派發器initApplicationEventMulticaster();//9.可以用于子類實現在容器刷新時自定義邏輯初始化onRefresh();// 10. 注冊時間監聽器,將ApplicationListener注冊到容器中來registerListeners();// 11. 初始化所有剩下的單實例bean,單例bean在初始化容器時創建,懶加載在調用的時候創建finishBeanFactoryInitialization(beanFactory);//12. 完成BeanFactory的初始化創建工作,IOC容器就創建完成finishRefresh();}catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}finally {// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();}}}refresh刷新上下文字方法1到12,bean的創建過程在第11個方法。具體bean的創建方法我們可以參考這篇文章Spring|容器初始化流程及源碼分析
總結
以上是生活随笔為你收集整理的Spring容器初始化和bean创建过程的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: Redis 命令字符串(String)
- 下一篇: (error) CROSSSLOT Ke
