以AnnotionConfigApplicationContext爲例,在new一個AnnotionConfigApplicationContext的時候,其構造函數內就會調用父類的refresh方法java
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { this(); register(annotatedClasses); refresh();// <-- 調用AbstractApplicationContext的refresh方法 }
因此呢,Spring容器的建立過程主要在這個refresh方法裏邊。spring
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 一、Prepare this context for refreshing. prepareRefresh(); ///二、Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); ///三、Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { //四、 Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); //五、 Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); //六、 Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); //七、 Initialize message source for this context. initMessageSource(); //八、 Initialize event multicaster for this context. initApplicationEventMulticaster(); //九、 Initialize other special beans in specific context subclasses. onRefresh(); //十、 Check for listener beans and register them. registerListeners(); //十一、 Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); //十二、 Last step: publish corresponding event. 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(); } } }
我給源碼的每一步都加了序號(1~12),下面來詳細看看每一步都作了些什麼。緩存
設置一些狀態標記,如啓動時間startupDate,closed/active狀態app
initPropertySources() 設置init屬性,此方法交給子類去實現函數
getEnvironment().validateRequiredProperties()post
若是無Environment,則new StandardEnvironment()ui
再調用validateRequiredProperties() 校驗參數this
earlyApplicationEvents= new LinkedHashSet
refreshBeanFactory() 刷新BeanFactorycode
在GenericApplicationContext的構造方法中new了一個DefaultListableBeanFactory
經過this.beanFactory.setSerializationId(getId());設置一個惟一的id
getBeanFactory() 返回剛纔GenericApplicationContext建立的BeanFactory對象
設置BeanFactory的類加載器、表達式解析器【StandardBeanExpressionResolver】、ResourceEditorRegistrar
添加BeanPostProcessor【ApplicationContextAwareProcessor】
設置不須要自動裝配的接口
包括【EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware】
註冊能夠解析的自動裝配的接口
包括【BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext】
添加BeanPostProcessor【ApplicationListenerDetector】
添加AspectJ【類加載時織入LoadTimeWeaver】
給BeanFactory中註冊一些能用的組件
environment【ConfigurableEnvironment】
systemProperties【Map<String, Object>】
systemEnvironment【Map<String, Object>】
子類經過重寫這個方法來在BeanFactory建立並預準備完成之後作進一步的設置
到這裏,BeanFactory的建立及後置處理工做就結束了
BeanFactoryPostProcessors是BeanFactory的後置處理器,在BeanFactory標準初始化以後、所有bean信息都被加載,可是尚未被實例化的時候執行。
在invokeBeanFactoryPostProcessors方法中,主要處理2種類型的接口:
BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor
■先執行BeanDefinitionRegistryPostProcessor的方法,過程以下:
獲取全部實現了BeanDefinitionRegistryPostProcessor接口的class
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false)
先執行實現了PriorityOrdered優先級接口的BeanDefinitionRegistryPostProcessor
postProcessor.postProcessBeanDefinitionRegistry(registry)
同理,再執行實現了Order順序接口的BeanDefinitionRegistryPostProcessor;最後執行其餘實現了BeanDefinitionRegistryPostProcessor的
Configuration類中經過@Import(ImportBeanDefinitionRegistrar)引入的類就是在這裏被調用registerBeanDefinitions方法的…【processor:ConfigurationClassPostProcessor】
java public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)
■再執行BeanFactoryPostProcessor的方法,過程以下:
獲取全部實現了BeanFactoryPostProcessor接口的class
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false)
先執行實現了PriorityOrdered優先級接口的BeanFactoryPostProcessor
postProcessor.postProcessBeanFactory(beanFactory)
同理,再執行實現了Order順序接口的BeanFactoryPostProcessor;最後執行其餘實現了BeanDefinitionRegistryPostProcessor的
獲取全部實現了BeanPostProcessor接口的class
beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
把獲取的類按照 是否實現了 PriorityOrdered、Ordered接口、及其餘 分紅3類
按照優先級依次調用
beanFactory.addBeanPostProcessor(postProcessor);
最後註冊一個ApplicationListenerDetector
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
這個Detector的做用是:
在Bean建立完成後檢查是不是ApplicationListener,若是是則加到context中applicationContext.addApplicationListener((ApplicationListener<?>) bean)
MessageSource組件主要用來實現國際化、消息解析處理。
在initMessageSource中,首先看容器中是否有id爲messageSource的,類型是MessageSource的組件。若是沒有則new DelegatingMessageSource() 放進去。
後面在處理國際化時,能夠注入MessageSource對象,而後使用以下代碼進行國際化
String getMessage(String code, Object[] args, Locale locale)
在此方法中,首選從BeanFactory中獲取id爲「applicationEventMulticaster」的ApplicationEventMulticaster。若是沒有就new SimpleApplicationEventMulticaster(beanFactory)放進去。[多波器,有的也叫派發器]
從容器中拿到全部的ApplicationListener
將每一個監聽器添加到事件多波器中
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName)
處理前面步驟留下的earlyApplicationEvents,earlyApplicationEvents在步驟1.4中初始化爲空的LinkedHashSet
getApplicationEventMulticaster().multicastEvent(earlyEvent)
核心邏輯在beanFactory.preInstantiateSingletons()方法中。這裏面作的事情主要有:
循環編譯全部的beanNames,獲取RootBeanDefinition
若是bean 不是抽象的,是單實例的,是懶加載
判斷是否 是實現FactoryBean接口的Bean
若是是,先作一些處理,再調getBean
若是不是,則直接調用getBean(beanName)
getBean(beanName) –> doGetBean(name, null, null, false)
先獲取緩存中保存的單實例Bean【singletonObjects.get(beanName)】。若是能獲取到說明這個Bean以前被建立過(全部建立過的單實例Bean都會被緩存在ConcurrentHashMap<String, Object>(256)中)
若是緩存中獲取不到,則開啓下面的建立流程
先將bean標記爲已建立 markBeanAsCreated(beanName)
獲取Bean的定義信息RootBeanDefinition
獲取當前Bean依賴的其餘Bean[mbd.getDependsOn()],若是有則調用getBean()把依賴的Bean先建立出來
開啓單實例Bean的建立流程 createBean(beanName, mbd, args)
準備重寫的方法
嘗試返回代理對象
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
執行InstantiationAwareBeanPostProcessor
先觸發:postProcessBeforeInstantiation();
若是BeforeInstantiation有返回值,再接着執行postProcessAfterInitialization();
若是resolveBeforeInstantiation返回的不爲null,則bean就建立好了
前面resolveBeforeInstantiation返回的不爲null,則返回該bean;爲null接着調Object beanInstance = doCreateBean(beanName, mbdToUse, args);建立Bean【step5】
建立doCreateBean(beanName, mbdToUse, args)
建立instanceWrapper = createBeanInstance(beanName, mbd, args)
利用工廠方法 或 對象的構造器 建立出Bean實例
調用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition(mbd, beanType, beanName);
給bean屬性賦值 populateBean(beanName, mbd, instanceWrapper)
賦值前,拿到全部的InstantiationAwareBeanPostProcessor後置處理器,調用postProcessAfterInstantiation()
再拿到全部的InstantiationAwareBeanPostProcessor後置處理器,調用postProcessPropertyValues()
賦值 applyPropertyValues(beanName, mbd, bw, pvs);
爲屬性利用setter方法等進行賦值
初始化bean,調用initializeBean(beanName, exposedObject, mbd)
執行xxxAware方法 invokeAwareMethods(beanName, bean),包括【BeanNameAware\BeanClassLoaderAware\BeanFactoryAware】
執行Bean後置處理器的before方法 applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName) 循環調用 beanProcessor.postProcessBeforeInitialization(result, beanName)
執行bean的初始化方法 invokeInitMethods(beanName, wrappedBean, mbd);
執行bean的後置處理器的after方法 applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName) 循環調用 beanProcessor.postProcessAfterInitialization(result, beanName)
Spring的AOP註解實現原理:
@EnableAspectJAutoProxy引入了繼承自AbstractAutoProxyCreator的AnnotationAwareAspectJAutoProxyCreator
在AbstractAutoProxyCreator中實現了postProcessAfterInitialization方法,在方法內調用wrapIfNecessary(bean, beanName, cacheKey)方法建立代理對象返回出去,後續放入容器的就是這個代理對象
註冊bean的銷燬方法 registerDisposableBeanIfNecessary(beanName, bean, mbd);
將bean加入到singletonObjects中
全部bean建立完以後,判斷bean是不是SmartInitializingSingleton的實例。若是是,就執行afterSingletonsInstantiated()
initLifecycleProcessor() 初始化和生命週期有關的後置處理器
默認從容器中找是否有lifecycleProcessor的組件【LifecycleProcessor】;若是沒有new DefaultLifecycleProcessor();加入到容器;
執行onfresh方法
getLifecycleProcessor().onRefresh()
發佈容器刷新完成事件
publishEvent(new ContextRefreshedEvent(this))
調用LiveBeansView.registerApplicationContext(this)