AnnotationConfigApplicationContext作為注解型IOC的入口
ClassPathXmlApplicationContext 作為XML IOC的入口
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
傳入一個Class對象
首先this()初始化reader和scanner,創(chuàng)建beanFactory虽惭,這個this其實是執(zhí)行了父類GenericApplicationContext中的初始化方法
/**
* Create a new GenericApplicationContext.
* @see #registerBeanDefinition
* @see #refresh
*/
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
他初始化了一個beanFactory琅束,beanFactory會記錄一些bean信息。
Register(class)通過AnnotatedBeanDefinitionReader去doRegisterBean()秕岛。
這里其實是把主類解析成BeanDefinition同時會解析主類上的注解會把配置類信息放進beanDefinitionMap蒂破。
refresh()方法,refresh是放在AbstractApplicationContext類中的抽象方法伪货,主要是對beanFactory進行一系列配置刷新袍啡。
refresh方法
- prepareBeanFactory()為 beanFactory 工廠添加一些單例內(nèi)置組件踩官,進行預處理
預埋三級緩存
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}
- invokeBeanFactoryPostProcessors() 一個后置方法允許我們按需注入暴露了ConfigurableListableBeanFactory 和BeanDefinitionRegistry 。找出來境输,排序然后重新注入蔗牡。主要是對實現(xiàn)后置處理器的方法的一個調(diào)用。
處理一些實現(xiàn)了后置處理器postProcessor的類嗅剖,然后調(diào)用postProcessor.postProcessBeanDefinitionRegistry(registry)
@Component
public class BeanDefinitionRegistryPostProcessorTest implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("A");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("B");
}
}
初始化的時候允許自由修改registry與beanFactory
- registerBeanPostProcessors() 這一步是向容器中注入實現(xiàn)了 BeanPostProcessor的類辩越。注意是注冊而非使用
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// Remove from old position, if any
this.beanPostProcessors.remove(beanPostProcessor);
// Track whether it is instantiation/destruction aware
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
// Add to end of list
this.beanPostProcessors.add(beanPostProcessor);
}
- initMessageSource() 初始化messageSource,對messageSource bean進行裝配信粮,messageSource是國際化文件
- initApplicationEventMulticaster()對BeanFactory中的ApplicationEventMulticaster的事件進行監(jiān)聽黔攒,通過實現(xiàn)ApplicationEventMulticaster接口來監(jiān)聽事件。如果沒有則采用SimpleApplicationEventMulticaster來監(jiān)聽事件强缘。初始化事件監(jiān)聽器亏钩,一種觀察者模式。
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
- registerListeners() 找出實現(xiàn)ApplicationListener的類裝配進applicationListeners欺旧。其實是放到ApplicationEventMulticaster 廣播器里。發(fā)布事件通知蛤签,對應(yīng)Listener會收到消息進行處理辞友。
- finishBeanFactoryInitialization() ,直接看里面調(diào)用的beanFactory.preInstantiateSingletons()
剩下來的這個步驟就是初始化所有剩余的單實例 bean震肮。RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName)獲取称龙。下面會根據(jù)是不是FactoryBean來選擇初始化方式。普通的直接走getBean()就行戳晌。transformedBeanName會獲得bean的真實名字
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
通過getBean()走到dogetBean()鲫尊。但其實里面最終都會走到getObjectForBeanInstance()。
在getObjectForBeanInstance()方法中會先判斷bean是不是FactoryBean沦偎,如果不是疫向,就直接返回Bean。
- 如果是FactoryBean豪嚎,且name是以&符號開頭搔驼,那么表示的是獲取FactoryBean的原生對象,也會直接返回侈询。如果name不是以&符號開頭舌涨,那么表示要獲取FactoryBean中g(shù)etObject()方法返回的對象即Bean.class。
- 接下來會先嘗試從緩存中獲取扔字,如果緩存中不存在則getObjectFromFactoryBean()然后doGetObjectFromFactoryBean()這樣走下去囊嘉。這是FactoryBean的流程温技。
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
再說一下dogetBean(),用到三級緩存的地方是getSingleton()方法扭粱,
singletonObjects一級緩存:單例對象緩存池舵鳞,beanName->Bean,其中存儲的是完整的Bean
earlySingletonObjects二級緩存早期的單例對象,beanName->ObjectFactory,存儲的是實例化后,屬性未賦值的單例對象
singletonFactories三級緩存:單例工廠的緩存焊刹,beanName->ObjectFactory,添加進去的時候?qū)嵗淳邆鋵傩?br>
一層一層往下找就是了系任,最后找不到調(diào)用singletonFactory.getObject()
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
- 嘗試從一級緩存中查找完整的Bean實例,找到則直接返回.
- 如果無法從一級緩存中查找虐块,對一級緩存進行上鎖俩滥,然后嘗試從二級緩存中查找半成品的Bean.找到直接返回.
- 從三級緩存中查找,找到則放入二級緩存,同時為了保證一個對象實例為單例贺奠,將該實例從第三級緩存中進行移除
在這里判斷的循環(huán)依賴霜旧,如果一個beanName可以從單力池里拿到實例,而他還在創(chuàng)建說明這個類循環(huán)依賴儡率,就還會走到getObjectForBeanInstance()方法拿到對象挂据。Spring對于循環(huán)依賴的處理時不是一個一個去找,而是直接看池子里有沒有儿普。
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
如果實在拿不到崎逃,就要開始創(chuàng)建了。首先會到ParentBeanFactory中進行遞歸查找眉孩。根據(jù)名稱和type个绍。對合并后的BeanDefinition進行檢測,主要是判斷是否為abstract浪汪,然后會找到所有依賴的Bean名稱巴柿,如果循環(huán)依賴直接拋異常,然后會遞歸走getBean死遭。
遞歸完成后走到getSingleton()走createBean()广恢。真正創(chuàng)建單例Bean前會檢測是否正在創(chuàng)建,做點預處理呀潭,最后都會走到createBean()钉迷。
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
進到createBean()。先獲取Bean的Class放到BeanDefinition钠署。經(jīng)過方法重載以及代理對象判斷后走到doCreateBean()篷牌。
這里會再進一次緩存,如果拿不到BeanWrapper(包裝類對象)則調(diào)用createBeanInstance()來創(chuàng)建Bean實例踏幻,此時獲取類的構(gòu)造方法createBean枷颊,即調(diào)用autowireConstructor(),最典型的應(yīng)用就是Autowire打在構(gòu)造方法上。mbd.getConstructorArgumentValues()可以從BeanDefinition中拿到構(gòu)造函數(shù)信息夭苗,通過resolveConstructorArguments()拿到參數(shù)信卡。
// Candidate constructors for autowiring?
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
這個時候會把BeanDefinition盡早放進SingletonFactory。然后會進行依賴注入题造,再看下屬性注入傍菇,走到populateBean()方法會通過BeanDefinition進行屬性判斷。這里會選擇名稱進行注入或者根據(jù)類型進行注入界赔。這里最后還是走getBean遞歸
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
通過名稱注入丢习,先通過 unsatisfiedNonSimpleProperties() 找到需要填充的所有屬性 name。然后遞歸getbean加載屬性
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
registerDependentBean(propertyName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
類型則是先通過 unsatisfiedNonSimpleProperties() 找到需要填充的所有屬性 name淮悼,根據(jù)傳入的參數(shù) pvs 中找出已經(jīng)加載的 bean咐低,并遞歸實例化,然后再加入到 pvs 中
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
if (Object.class != pd.getPropertyType()) {
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
registerDependentBean(autowiredBeanName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();
}
}