- 定義
bean的生命周期指的是在Spring中IOC容器從初始化到銷毀這一整個(gè)全過程宪迟。同時(shí)在這一過程里關(guān)系到各個(gè)級別的接口的作用和自定義實(shí)現(xiàn)。
先簡單說一下bean的整個(gè)生命周期:創(chuàng)建(實(shí)例化、屬性賦值、初始化)驮履、使用、銷毀苗桂。而spring提供了一些接口允許在這個(gè)過程中進(jìn)行一定程度的擴(kuò)展。
- 各個(gè)級別的接口
- 工廠后處理器接口方法:諸如BeanFactoryPostProcessor告组,CustomAutowireConfigure等煤伟,它們是在容器裝置配置文件之后調(diào)用,可以說是最先調(diào)用的方法了木缝。
- 容器級生命周期接口方法:InstantiationAwareBeanPostProcessor(繼承自BeanPostProcessor) 和BeanPostProcessor 這兩個(gè)的接口的實(shí)現(xiàn)便锨。我們一般稱之為后置處理器
- Bean級別生命周期接口:BeanNameAware,BeanFactoryAware我碟,IntializaingBean放案,DiposableBean 這些接口的方法。每個(gè)Bean都可以選擇實(shí)現(xiàn)矫俺,可以選擇各自的自定義操作
- Bean自身的方法:init-method / destory-method 吱殉, 通過在配置文件bean定義的相應(yīng)屬性中掸冤,指定相應(yīng)的執(zhí)行方法。
現(xiàn)在我們具體的來說一下整個(gè)生命周期以及相關(guān)的接口的方法執(zhí)行的時(shí)機(jī):
直接上一段代碼:
package com.suxin;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
//DDDbean繼承自BeanFactoryPostProcessor 是一個(gè)工廠后置處理器
public class DDDbean implements BeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("DDDbean...BeanFactoryPostProcessor.postProcessBeanFactory 執(zhí)行中...");
}
public DDDbean() {
System.out.println("DDDbean.構(gòu)造方法 執(zhí)行中...");
}
}
package com.suxin;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import java.beans.PropertyDescriptor;
//EEEbean實(shí)現(xiàn)了InstantiationAwareBeanPostProcessor 接口(該接口是一個(gè)容器級別的生命周期的接口方法)
public class EEEbean implements InstantiationAwareBeanPostProcessor {
private String name;
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("EEEbean...InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation 執(zhí)行中...");
return null;
}
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("EEEbean...InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 執(zhí)行中...");
return true;
}
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
System.out.println("EEEbean...InstantiationAwareBeanPostProcessor.postProcessPropertyValues 執(zhí)行中...");
return pvs;
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("EEEbean...InstantiationAwareBeanPostProcessor.postProcessBeforeInitialization 執(zhí)行中...");
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("EEEbean...InstantiationAwareBeanPostProcessor.postProcessAfterInitialization 執(zhí)行中...");
return bean;
}
public EEEbean() {
System.out.println("EEEbean.構(gòu)造方法 執(zhí)行中...");
}
public String getName() {
System.out.println("EEEbean.getName 執(zhí)行中...");
return name;
}
public void setName(String name) {
System.out.println("EEEbean.setName 執(zhí)行中...");
this.name = name;
}
}
package com.suxin;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
//FFFbean實(shí)現(xiàn)了BeanNameAware考婴、BeanFactoryAware贩虾、IntializaingBean催烘、DiposableBean 這四種bean級別的生命周期接口方法
//同時(shí)也寫了initMethod和destroyMethod倆種方法即將裝配到xml的bean配置里的init-method和destroy-method屬性
public class FFFbean implements BeanNameAware, BeanFactoryAware, InitializingBean,DisposableBean {
private String value;
public void setBeanName(String name) {
System.out.println("FFFbean.setBeanName 執(zhí)行中..."+name);
}
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("FFFbean.setBeanFactory 執(zhí)行中...");
}
public void afterPropertiesSet() throws Exception {
System.out.println("FFFbean.afterPropertiesSet 執(zhí)行中...");
}
public void destroy() throws Exception {
System.out.println("FFFbean.destroy 執(zhí)行中...");
}
public FFFbean() {
System.out.println("FFFbean.構(gòu)造方法 執(zhí)行中...");
}
public void doSomething() {
System.out.println("doSomething...");
}
public String getValue() {
System.out.println("FFFbean.getValue 執(zhí)行中... " + value);
return value;
}
public void setValue(String value) {
System.out.println("FFFbean.setValue 執(zhí)行中... " + value);
this.value = value;
}
public void initMethod() {
System.out.println("FFFbean.initMethod...");
}
public void destroyMethod() {
System.out.println("FFFbean.destroyMethod...");
}
}
xml配置相關(guān):
<bean id="dDDbean" class="com.suxin.DDDbean"></bean>
<bean id="eEEbean" class="com.suxin.EEEbean">
<property name="name" value="lalala"></property>
</bean>
<bean id="fFFbean" class="com.suxin.FFFbean" init-method="initMethod" destroy-method="destroyMethod">
<property name="value" value="jiujiu"></property>
</bean>
運(yùn)行main方法
public class App {
public static void main( String[] args ) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
FFFbean fFFbean= (FFFbean)context.getBean("fFFbean");
fFFbean.doSomething();
// context.getAutowireCapableBeanFactory().destroyBean(fFFbean);
context.close();
執(zhí)行結(jié)果
八月 10, 2019 1:43:17 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2e0fa5d3: startup date [Sat Aug 10 13:43:17 CST 2019]; root of context hierarchy
八月 10, 2019 1:43:17 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans.xml]
DDDbean.構(gòu)造方法 執(zhí)行中...
DDDbean...BeanFactoryPostProcessor.postProcessBeanFactory 執(zhí)行中...
EEEbean.構(gòu)造方法 執(zhí)行中...
EEEbean.setName 執(zhí)行中...
EEEbean...InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation 執(zhí)行中...
FFFbean.構(gòu)造方法 執(zhí)行中...
EEEbean...InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 執(zhí)行中...
EEEbean...InstantiationAwareBeanPostProcessor.postProcessPropertyValues 執(zhí)行中...
FFFbean.setValue 執(zhí)行中... jiujiu
FFFbean.setBeanName 執(zhí)行中...fFFbean
FFFbean.setBeanFactory 執(zhí)行中...
EEEbean...InstantiationAwareBeanPostProcessor.postProcessBeforeInitialization 執(zhí)行中...
FFFbean.afterPropertiesSet 執(zhí)行中...
FFFbean.initMethod...
EEEbean...InstantiationAwareBeanPostProcessor.postProcessAfterInitialization 執(zhí)行中...
doSomething...
八月 10, 2019 1:43:19 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@2e0fa5d3: startup date [Sat Aug 10 13:43:17 CST 2019]; root of context hierarchy
FFFbean.destroy 執(zhí)行中...
FFFbean.destroyMethod...
Process finished with exit code 0
ok沥阱,代碼相關(guān)已經(jīng)貼完,我們開始來解釋一下伊群。當(dāng)然以上代碼如果感興趣可以直接復(fù)制下來考杉,自己運(yùn)行一遍,加深印象舰始。
貼一段AbstractApplicationContext的refresh方法的源碼崇棠,我會(huì)忽略一些不是本章關(guān)注的代碼
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// ...
// Tell the subclass to refresh the internal bean factory.
// ...
// Prepare the bean factory for use in this context.
// ...
try {
// 讓繼承容器的子類容器進(jìn)行擴(kuò)展的
postProcessBeanFactory(beanFactory);
// 創(chuàng)建BeanFactoryPostProcessor實(shí)例,并且調(diào)用相關(guān)方法丸卷,也就是在這個(gè)方法里DDDbean會(huì)被初始化枕稀,且會(huì)被調(diào)用相關(guān)方法
invokeBeanFactoryPostProcessors(beanFactory);
// 初始化實(shí)現(xiàn)了BeanPostProcessor 和 InstantiationAwareBeanPostProcessor接口方法的bean,也就是說這里EEEbean被初始化 ps:還未調(diào)用相關(guān)方法
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// ...
// Initialize event multicaster for this context.
// ...
// Initialize other special beans in specific context subclasses.
// ...
// Check for listener beans and register them.
// ...
// 完成初始化的工作谜嫉,等會(huì)會(huì)深入進(jìn)入看看
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// ...
}
catch (BeansException ex) {
// ...
// Destroy already created singletons to avoid dangling resources.
// ...
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// 重置Spring核心中常見的默認(rèn)緩存萎坷,因?yàn)槲覀? // 可能不再需要用于單例bean的元數(shù)據(jù)了…
resetCommonCaches();
}
}
}
首先是DDDbean的構(gòu)造方法被執(zhí)行了,然后繼續(xù)執(zhí)行這個(gè)bean的實(shí)現(xiàn)了BeanFactoryPostProcessor的postProcessBeanFactory方法沐兰。ok第一步已經(jīng)出來了BeanFactoryPostProcessor這種級別的bean會(huì)被首先初始化然后緊接著就是調(diào)用該bean的postProcessBeanFactory方法哆档。
其發(fā)生的時(shí)機(jī)就是在AbstractApplicationContext的refresh方法里的調(diào)用invokeBeanFactoryPostProcessors方法
貼一段invokeBeanFactoryPostProcessors的源碼(已經(jīng)刪除非重點(diǎn)代碼):
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
//繼續(xù)看代碼
//PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
//這是個(gè)靜態(tài)方法,由于代碼很多我就忽略了非本章關(guān)注的代碼
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<String>();
// ......
// 獲取到所有工廠后處理器接口實(shí)現(xiàn)類的名字,DDDbean的名字就包含在里面
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 為容器內(nèi)的BeanFactoryPostProcessor規(guī)定創(chuàng)建順序和執(zhí)行方法的順序
// 優(yōu)先級最高的是priorityOrdered住闯,其次是ordered瓜浸,最后的是nonOrdered
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
// ......
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
// ......
// 關(guān)注這個(gè)部分,DDDbean即將在這里被初始化然后調(diào)用它的方法
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// 清除緩存的合并bean定義比原,因?yàn)楹筇幚砥骺赡? // 修改了原始元數(shù)據(jù)插佛,例如替換值中的占位符…
beanFactory.clearMetadataCache();
}
通過源碼解讀,我們可以了解到為什么DDDbean會(huì)優(yōu)先被初始化且被調(diào)用實(shí)現(xiàn)的postProcessBeanFactory方法量窘。
接下來我們繼續(xù)看到EEEbean被初始化(實(shí)例化+屬性賦值)朗涩,且相對于FFFbean來說是優(yōu)先初始化。繼續(xù)看源碼绑改,這一次我們深入到registerBeanPostProcessors(beanFactory)方法里去看谢床。非本章關(guān)注代碼已經(jīng)忽略
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
//繼續(xù)深入進(jìn)去看 省略無關(guān)代碼
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 獲取到了EEEbean的名字放在了postProcessorNames 數(shù)組里面
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
// ......
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
List<String> orderedPostProcessorNames = new ArrayList<String>();
List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
//關(guān)注一下這個(gè)方法 EEEbean的名字被放到這個(gè)集合里面
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
// ......
// Next, register the BeanPostProcessors that implement Ordered.
// ......
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
for (String ppName : nonOrderedPostProcessorNames) {
// 關(guān)注點(diǎn)在這里,初始化BeanPostProcessor相關(guān)類 也就是EEEbean在這里進(jìn)行初始化(實(shí)例化+屬性賦值)
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
// ......
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
// ......
}
OK通過上面的源碼解釋了為什么EEEbean先FFFbean一步進(jìn)行初始化了厘线。
繼續(xù)看源碼refresh方法里finishBeanFactoryInitialization(beanFactory)的方法
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// ... ...
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
// ......
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
// ......
// Stop using the temporary ClassLoader for type matching.
// ......
// Allow for caching all bean definition metadata, not expecting further changes.
// ......
// 重點(diǎn)關(guān)注方法
beanFactory.preInstantiateSingletons();
}
繼續(xù)看beanFactory.preInstantiateSingletons();
public void preInstantiateSingletons() throws BeansException {
// ......
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
// ......
}
else {
//重點(diǎn)方法 關(guān)注一波
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
// ......
}
繼續(xù)看getBean方法识腿,其實(shí)就是看doGetBean方法(繼續(xù)省略不是本章關(guān)注重點(diǎn)的代碼):
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
// ......
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// ......
// Check if bean definition exists in this factory.
// ......
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// ......
// 關(guān)注單例的bean的創(chuàng)建 重點(diǎn)關(guān)注createBean方法
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
// 重點(diǎn)就這個(gè)方法里
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
// ......
}
else {
// ......
catch (IllegalStateException ex) {
// ......
}
}
}
catch (BeansException ex) {
// ......
}
}
// Check if required type matches the type of the actual bean instance.
// ......
return (T) bean;
}
繼續(xù)看createBean的方法(同樣還是忽略不必要的代碼)
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
// ......
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// ......
// Prepare method overrides.
// ......
try {
// 首先關(guān)注這個(gè)方法
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
//docreateBean的方法依然是我們關(guān)注的重點(diǎn)。
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
// ......
return beanInstance;
}
ok造壮,通過上面的代碼我們已經(jīng)提煉處我們需要關(guān)注的倆個(gè)方法:resolveBeforeInstantiation(beanName, mbdToUse)和doCreateBean(beanName, mbdToUse, args)渡讼,ok我們一個(gè)個(gè)來看:
首先是resolveBeforeInstantiation的源碼:
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//就是這里會(huì)調(diào)用一次EEEbean的postProcessBeforeInstantiation方法骂束,
// 具體的方法大家進(jìn)去看一下非常簡單。
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
上面的代碼說明了EEEbean會(huì)被調(diào)用實(shí)現(xiàn)的postProcessBeforeInstantiation方法成箫,同時(shí)因?yàn)樵摲椒ㄔ贓EEbean的實(shí)現(xiàn)里返回的是一個(gè)null展箱,所以不會(huì)立即執(zhí)行EEEbean的postProcessAfterInstantiation方法,會(huì)放在后面來執(zhí)行蹬昌。(對了此時(shí)我們得明白一下現(xiàn)在的情況混驰,DDDbean和EEEbean已經(jīng)被初始化了,但是FFFbean還沒有完成初始化(按照目前的這個(gè)代碼進(jìn)度來說FFFbean的實(shí)例化還未完成))
繼續(xù),我們來看doCreateBean方法代碼
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//關(guān)注一下這里皂贩,在這里會(huì)完成FFFbean的實(shí)例化栖榨,也就是FFFbean的構(gòu)造方法會(huì)被調(diào)用
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// Allow post-processors to modify the merged bean definition.
// ......
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// ......
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 關(guān)注這個(gè)方法,會(huì)完成FFFbean的屬性注入
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
// 關(guān)注這個(gè)方法明刷,完成bean的相關(guān)實(shí)現(xiàn)方法的回調(diào)
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
catch (Throwable ex) {
// ......
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
通過上面的源碼我們可以看到主要有三個(gè)方法值得關(guān)注createBeanInstance婴栽、populateBean、initializeBean辈末。createBeanInstance完成了FFFbean的實(shí)例化(也就是調(diào)用了FFFbean的構(gòu)造方法)
我們來重點(diǎn)關(guān)注一下populateBean方法
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
// ......
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//關(guān)注這里愚争,解釋了為什么EEEbean執(zhí)行了postProcessAfterInstantiation方法
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
// ......
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
//關(guān)注一下這里,會(huì)執(zhí)行EEEbean的postProcessPropertyValues方法
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
//執(zhí)行FFFbean的賦值操作挤聘,F(xiàn)FFbean的setValue方法
applyPropertyValues(beanName, mbd, bw, pvs);
}
以上轰枝,populateBean方法解釋完了,DDDbean和EEEbean都已經(jīng)被初始化了而FFFbean已經(jīng)完成了實(shí)例化和屬性注值檬洞,現(xiàn)在就差FFFbean的實(shí)現(xiàn)相關(guān)接口的方法回調(diào)了狸膏。我們繼續(xù)看initializeBean方法。
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
//重點(diǎn)關(guān)注一下這個(gè)方法添怔,回調(diào)了FFFbean實(shí)現(xiàn)了
//BeanNameAware和BeanFactoryAware接口的方法,具體的
//大家點(diǎn)擊進(jìn)去看一下湾戳,代碼很簡單
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//關(guān)注重點(diǎn) 此方法里回調(diào)了EEEbean的postProcessBeforeInitialization方法,大家可以自己點(diǎn)進(jìn)去广料,非常簡單明了
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//關(guān)注重點(diǎn) 在這個(gè)方法里主要執(zhí)行了FFFbean實(shí)現(xiàn)了InitializingBean接口的方法和自身initMethod屬性的方法砾脑。
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()) {
//關(guān)注重點(diǎn) 此方法里回調(diào)了EEEbean的postProcessAfterInitialization方法,大家可以自己點(diǎn)進(jìn)去艾杏,非常簡單明了
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
至此韧衣,F(xiàn)FFbean完成了初始化的所有工作(實(shí)例化+屬性注入+接口方法回調(diào)),而且整個(gè)控制臺(tái)打印的東西里doSomething之前的打印部分已經(jīng)解釋完畢购桑。我們現(xiàn)在再把整個(gè)空調(diào)臺(tái)打印的東西展示一下畅铭,防止大家忘記:
八月 10, 2019 1:43:17 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2e0fa5d3: startup date [Sat Aug 10 13:43:17 CST 2019]; root of context hierarchy
八月 10, 2019 1:43:17 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans.xml]
DDDbean.構(gòu)造方法 執(zhí)行中...
DDDbean...BeanFactoryPostProcessor.postProcessBeanFactory 執(zhí)行中...
EEEbean.構(gòu)造方法 執(zhí)行中...
EEEbean.setName 執(zhí)行中...
EEEbean...InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation 執(zhí)行中...
FFFbean.構(gòu)造方法 執(zhí)行中...
EEEbean...InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 執(zhí)行中...
EEEbean...InstantiationAwareBeanPostProcessor.postProcessPropertyValues 執(zhí)行中...
FFFbean.setValue 執(zhí)行中... jiujiu
FFFbean.setBeanName 執(zhí)行中...fFFbean
FFFbean.setBeanFactory 執(zhí)行中...
EEEbean...InstantiationAwareBeanPostProcessor.postProcessBeforeInitialization 執(zhí)行中...
FFFbean.afterPropertiesSet 執(zhí)行中...
FFFbean.initMethod...
EEEbean...InstantiationAwareBeanPostProcessor.postProcessAfterInitialization 執(zhí)行中...
doSomething...
八月 10, 2019 1:43:19 下午 org.springframework.context.support.ClassPathXmlApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@2e0fa5d3: startup date [Sat Aug 10 13:43:17 CST 2019]; root of context hierarchy
FFFbean.destroy 執(zhí)行中...
FFFbean.destroyMethod...
Process finished with exit code 0
接著我們把main方法的代碼再次展示一下:
public class App {
public static void main( String[] args ) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
FFFbean fFFbean= (FFFbean)context.getBean("fFFbean");
fFFbean.doSomething();
// context.getAutowireCapableBeanFactory().destroyBean(fFFbean);
context.close();
ok,fffbean對象執(zhí)行了doSomething方法勃蜘。緊接著就是容器的關(guān)閉硕噩。
在容器關(guān)閉的方法里,會(huì)先調(diào)用FFFbean實(shí)現(xiàn)DisposableBean的destroy方法缭贡,然后再接著調(diào)用FFFbean本身的destoryMethod屬性里的方法
具體的感興趣的可以自己看源碼一步步的debug炉擅。
跟著源碼走一遍辉懒,估計(jì)大家這會(huì)都有點(diǎn)暈乎了,我們來做一些總結(jié)吧:
首先Spring的bean的生命周期只有五步:實(shí)例化谍失、屬性賦值眶俩、初始化、使用快鱼、銷毀颠印。
實(shí)例化、屬性賦值攒巍、初始化分別對應(yīng)三個(gè)方法嗽仪,都是在doCreateBean方法里面荒勇,也就是createBeanInstance柒莉、populateBean、initializeBean沽翔。
說完了bean的生命周期兢孝,我們來說一下各個(gè)接口的方法調(diào)用的時(shí)機(jī)。
BeanFactoryPostProcessor類型的接口bean是最先被創(chuàng)建(實(shí)例化仅偎、屬性注入跨蟹、初始化)并且被調(diào)用的postProcessBeanFactory方法的。該時(shí)機(jī)是refresh方法里的invokeBeanFactoryPostProcessors方法里橘沥。refresh的registerBeanPostProcessors方法里主要是做了BeanPostProcessor類型(包括InstantiationAwareBeanPostProcessor)的創(chuàng)建(實(shí)例化窗轩、屬性注入、初始化)座咆,而InstantiationAwareBeanPostProcessor類型的方法調(diào)用的時(shí)機(jī)是在doCreateBean里痢艺。
InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法會(huì)在createBeanInstance(實(shí)例化)之前調(diào)用,而它的postProcessAfterInstantiation方法則會(huì)在createBeanInstance(實(shí)例化)之后調(diào)用介陶。在populateBean(屬性注入)方法里會(huì)調(diào)用它的postProcessPropertyValues堤舒。
接下來就是各種bean級別的生命周期接口諸如beanNameAware、BeanFactoryAware都會(huì)在initializeBean(初始化方法里)里面首先調(diào)用哺呜,然后調(diào)用的是BeanPostProcessor接口的postProcessBeforeInitialization方法舌缤,后面接著就是InitializingBean接口的afterPropertiesSet方法,最后再次調(diào)用BeanPostProcessor接口的postProcessAfterInitialization方法某残。
說完了創(chuàng)建階段国撵,再說一下銷毀階段,銷毀階段就是先調(diào)用DisposableBean接口的destroy方法玻墅,然后再調(diào)用bean自身的destroyMethod關(guān)聯(lián)的方法介牙。
至此整個(gè)bean的生命周期和接口方法的擴(kuò)展時(shí)機(jī)我們就說完了,可能有點(diǎn)多有點(diǎn)雜椭豫,大家多看看耻瑟,最好能根據(jù)我的代碼自己跑一遍debug一遍旨指,相信就會(huì)了解的更加深刻。