主要邏輯都在doCreate()方法中(context.getBean("designFactoryBean")時) getBean(beanName) 這個方法常常用來從 BeanFactory 中獲取一個 Bean,而初始化的過程也封裝到了這個方法裏。bash
// 實例化階段!
instanceWrapper = createBeanInstance(beanName, mbd, args);
複製代碼
觸點:在factoryBean 的 doCreateBean() 方法app
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
......
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
......
}
複製代碼
postProcessBeforeInstantiation接口的Before在doCreateBean以前調用,也就是在bean實例化以前調用的,英文源碼註釋解釋道該方法的返回值會替換本來的Bean做爲代理,這也是Aop等功能實現的關鍵點。源碼分析
createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args)
執行順序
Constructor構造方法 --> @PostConstruct註解標記的方法
複製代碼
// 屬性賦值階段!
populateBean(beanName, mbd, instanceWrapper);
複製代碼
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
......
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
......
}
複製代碼
// 初始化階段!
exposedObject = initializeBean(beanName, exposedObject, mbd);
複製代碼
無所不知的Aware。 Aware類型的接口的做用就是讓咱們可以拿到Spring容器中的一些資源。基本都可以見名知意,Aware以前的名字就是能夠拿到什麼資源,例如BeanNameAware能夠拿到BeanName,以此類推。調用時機須要注意:全部的Aware方法都是在初始化階段以前調用的!post
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
......
// 這裏調用的是三個Bean開頭的Aware: BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
invokeAwareMethods(beanName, bean);
......
// 這裏調用的是EnvironmentAware、EmbeddedValueResolverAware、ApplicationContextAware
// 藉助 BeanPostProcessor#postProcessBeforeInitialization()實現的invokeAwareInterfaces。(ApplicationContextAwareProcessor)
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
......
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
複製代碼
if (mbd == null || !mbd.isSynthetic()) {
//若是其中某一個後置處理器返回爲null,則後續的後置處理器將再也不調用,而直接返回
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
複製代碼
// invokeInitMethods方法中
((InitializingBean) bean).afterPropertiesSet()
複製代碼
// 調用自定義的init-method 方法(xml中配置的,或@Bean註解中配置的)
invokeCustomInitMethod(beanName, bean, mbd);
複製代碼
if (mbd == null || !mbd.isSynthetic()) {
//若是其中某一個後置處理器返回爲null,則後續的後置處理器將再也不調用,而直接返回
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
複製代碼
在容器關閉時調用的,詳見ConfigurableApplicationContext#close()ui
以ConfigurableApplicationContext#close()方法做爲入口,實現是經過循環取全部實現了DisposableBean接口的Bean而後調用其destroy()方法spa
執行順序
@PreDestroy --> DisposableBean --> destroy-method
複製代碼
~ end3d