Spring容器的創建刷新過程
以AnnotionConfigApplicationContext為例,在new一個AnnotionConfigApplicationContext的時候,其構造函數內就會調用父類的refresh方法
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
this();
register(annotatedClasses);
refresh();// <-- 調用AbstractApplicationContext的refresh方法
}
所以呢,Spring容器的創建過程主要在這個refresh方法里邊。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1、Prepare this context for refreshing.
prepareRefresh();
///2、Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
///3、Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
//4、 Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
//5、 Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
//6、 Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
//7、 Initialize message source for this context.
initMessageSource();
//8、 Initialize event multicaster for this context.
initApplicationEventMulticaster();
//9、 Initialize other special beans in specific context subclasses.
onRefresh();
//10、 Check for listener beans and register them.
registerListeners();
//11、 Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
//12、 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),下面來詳細看看每一步都做了些什么。
1、prepareRefresh() 刷新前准備
-
設置一些狀態標記,如啟動時間startupDate,closed/active狀態
-
initPropertySources() 設置init屬性,此方法交給子類去實現
-
getEnvironment().validateRequiredProperties()
如果無Environment,則new StandardEnvironment()
再調用validateRequiredProperties() 校驗參數
-
earlyApplicationEvents= new LinkedHashSet
();保存容器中的一些早期的事件
2、obtainFreshBeanFactory() 獲取BeanFactory
-
refreshBeanFactory() 刷新BeanFactory
在GenericApplicationContext的構造方法中new了一個DefaultListableBeanFactory
通過this.beanFactory.setSerializationId(getId());設置一個唯一的id
-
getBeanFactory() 返回剛才GenericApplicationContext創建的BeanFactory對象
3、prepareBeanFactory(beanFactory) 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>】
-
4、postProcessBeanFactory(beanFactory) BeanFactory后置處理
子類通過重寫這個方法來在BeanFactory創建並預准備完成以后做進一步的設置
到這里,BeanFactory的創建及后置處理工作就結束了
5、invokeBeanFactoryPostProcessors(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】
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry)
■再執行BeanFactoryPostProcessor的方法,過程如下:
-
獲取所有實現了BeanFactoryPostProcessor接口的class
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false)
-
先執行實現了PriorityOrdered優先級接口的BeanFactoryPostProcessor
postProcessor.postProcessBeanFactory(beanFactory)
-
同理,再執行實現了Order順序接口的BeanFactoryPostProcessor;最后執行其他實現了BeanDefinitionRegistryPostProcessor的
6、registerBeanPostProcessors(beanFactory) 注冊bean的后置處理器
-
獲取所有實現了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)
7、initMessageSource() 初始化MessageSource組件
MessageSource組件主要用來實現國際化、消息解析處理。
在initMessageSource中,首先看容器中是否有id為messageSource的,類型是MessageSource的組件。如果沒有則new DelegatingMessageSource() 放進去。
后面在處理國際化時,可以注入MessageSource對象,然后使用如下代碼進行國際化
String getMessage(String code, Object[] args, Locale locale)
8、initApplicationEventMulticaster() 初始化事件多波器
在此方法中,首選從BeanFactory中獲取id為“applicationEventMulticaster”的ApplicationEventMulticaster。如果沒有就new SimpleApplicationEventMulticaster(beanFactory)放進去。[多波器,有的也叫派發器]
9、onRefresh() 留給子類重寫
10、registerListeners() 注冊事件監聽器
-
從容器中拿到所有的ApplicationListener
-
將每個監聽器添加到事件多波器中
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName)
-
處理前面步驟留下的earlyApplicationEvents,earlyApplicationEvents在步驟1.4中初始化為空的LinkedHashSet
getApplicationEventMulticaster().multicastEvent(earlyEvent)
11、finishBeanFactoryInitialization(beanFactory) 初始化所有剩下的單實例bean
核心邏輯在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()
12、finishRefresh() 容器創建完成
-
initLifecycleProcessor() 初始化和生命周期有關的后置處理器
默認從容器中找是否有lifecycleProcessor的組件【LifecycleProcessor】;如果沒有new DefaultLifecycleProcessor();加入到容器;
-
執行onfresh方法
getLifecycleProcessor().onRefresh()
-
發布容器刷新完成事件
publishEvent(new ContextRefreshedEvent(this))
-
調用LiveBeansView.registerApplicationContext(this)