距離上一次寫Spring源碼解析,已通過去了快要好幾個月了,主要緣由仍是Spring的源碼解析類文章太難寫了,不像我先前寫的什麼CAS源碼,AQS源碼,LinkedBlockingQueue等等,這些無非就是分析幾個核心方法,代碼也不算太長,就像比較複雜的AQS源碼也是兩篇搞定的,雖然AQS源碼也不少東西也不能算是百分百的理解,可是核心思想應該是還算理解的。解析完畢成就感也滿滿的,寫完博客,看着大段大段的文字,內心也很開心:哈哈哈,原來JDK源碼也是能夠讀懂的,並且還能寫出來。可是Spring源碼就不同了,若是和先前的源碼分析類文章同樣逐行去解析的話,那麼可能一篇博客寫下來,一個小小小小小方法都無法分析完,就算分析完畢了,也突出不了重點啊,可是Spring源碼解析仍是要繼續的,就當作是本身的學習筆記把。html
今天咱們要看的內容是Spring Bean的生命週期,固然本篇博客只是帶着你們俯瞰下,不會進行過多的源碼分析,甚至只是貼下代碼,不作分析,只是找到Spring Bean生命週期的回調或者鉤子,固然這可能只是個人我的理解,你們仍是要以懷疑的目光看待,也許我分析的是有問題的。面試
不知道Spring官方對Bean的生命問題是否有明確的定義或者解析,可是Spring In Action以及市面上流傳的大部分博客是這樣的:spring
爲了驗證上面的邏輯,能夠作個試驗:app
首先定義了一個Bean,裏面有各類回調和鉤子,其中須要注意下,我在SpringBean的構造方法中打印了studentService,看SpringBean被new的出來的時候,studentService是否被注入了;又在setBeanName中打印了studentService,看此時studentService是否被注入了,以此來驗證,Bean是什麼時候完成的自動注入的(這個StudentServiceImpl 類的代碼就不貼出來了,無非就是一個最普通的Bean):ide
public class SpringBean implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware, BeanClassLoaderAware { public SpringBean() { System.out.println("SpringBean構造方法:" + studentService); System.out.println("SpringBean構造方法"); } @Autowired StudentServiceImpl studentService; @Override public void afterPropertiesSet() throws Exception { System.out.println("afterPropertiesSet"); } @Override public void destroy() throws Exception { System.out.println("destroy"); } @Override public void setBeanClassLoader(ClassLoader classLoader) { System.out.println("setBeanClassLoader"); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("setBeanFactory"); } @Override public void setBeanName(String name) { System.out.println("setBeanName:" + studentService); System.out.println("setBeanName"); } public void initMethod() { System.out.println("initMethod"); } public void destroyMethod() { System.out.println("destroyMethod"); } }
再定義一個BeanPostProcessor,在重寫的兩個方法中進行了判斷,若是傳進來的beanName是springBean才進行打印:函數
@Component public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if(beanName.equals("springBean")) { System.out.println("postProcessBeforeInitialization"); } return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if(beanName.equals("springBean")) { System.out.println("postProcessAfterInitialization"); } return bean; } }
定義一個配置類,完成自動掃描,可是SpringBean是手動註冊的,而且聲明瞭initMethod和destroyMethod:源碼分析
@Configuration @ComponentScan public class AppConfig { @Bean(initMethod = "initMethod",destroyMethod = "destroyMethod") public SpringBean springBean() { return new SpringBean(); } }
最後就是啓動類了:post
public static void main(String[] args) { AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class); annotationConfigApplicationContext.destroy(); }
運行結果:學習
SpringBean構造方法:null SpringBean構造方法 setBeanName:com.codebear.StudentServiceImpl@31190526 setBeanName setBeanClassLoader setBeanFactory postProcessBeforeInitialization afterPropertiesSet initMethod postProcessAfterInitialization destroy destroyMethod
能夠看到,試驗結果和上面分析的徹底一致。this
這就是廣爲流傳的Spring生命週期。
也許你在應付面試的時候,是死記硬背這些結論的,如今我帶着你找到這些方法,跟我來。
首先咱們來到AnnotationConfigApplicationContext的構造方法:
//根據參數類型能夠知道,其實能夠傳入多個annotatedClasses,可是這種狀況出現的比較少 public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { //調用無參構造函數,會先調用父類GenericApplicationContext的構造函數 //父類的構造函數裏面就是初始化DefaultListableBeanFactory,而且賦值給beanFactory //本類的構造函數裏面,初始化了一個讀取器:AnnotatedBeanDefinitionReader read,一個掃描器ClassPathBeanDefinitionScanner scanner //scanner的用處不是很大,它僅僅是在咱們外部手動調用 .scan 等方法纔有用,常規方式是不會用到scanner對象的 this(); //把傳入的類進行註冊,這裏有兩個狀況, //傳入傳統的配置類 //傳入bean(雖然通常沒有人會這麼作 //看到後面會知道spring把傳統的帶上@Configuration的配置類稱之爲FULL配置類,不帶@Configuration的稱之爲Lite配置類 //可是咱們這裏先把帶上@Configuration的配置類稱之爲傳統配置類,不帶的稱之爲普通bean register(annotatedClasses); //刷新 refresh(); }
進入refresh方法,refresh方法中有一個finishBeanFactoryInitialization小方法,這個方法是用來實例化懶加載單例Bean的,也就是咱們的Bean都是在這裏被建立出來的(固然我這裏說的的是絕大部分狀況是這樣的):
finishBeanFactoryInitialization(beanFactory);
咱們再進入finishBeanFactoryInitialization這方法,裏面有一個beanFactory.preInstantiateSingletons()方法:
//初始化全部的非懶加載單例 beanFactory.preInstantiateSingletons();
咱們嘗試再點進去,這個時候你會發現這是一個接口,好在它只有一個實現類,因此能夠咱們來到了他的惟一實現,實現類就是org.springframework.beans.factory.support.DefaultListableBeanFactory,這裏面是一個循環,咱們的Bean就是循環被建立出來的,咱們找到其中的getBean方法:
getBean(beanName);
這裏有一個分支,若是Bean是FactoryBean,如何如何,若是Bean不是FactoryBean如何如何,好在不論是不是FactoryBean,最終仍是會調用getBean方法,因此咱們能夠堅決果斷的點進去,點進去以後,你會發現,這是一個門面方法,直接調用了doGetBean方法:
return doGetBean(name, null, null, false);
再進去,不斷的深刻,接近咱們要尋找的東西。 這裏面的比較複雜,可是有我在,我能夠直接告訴你,下一步咱們要進入哪裏,咱們要進入
if (mbd.isSingleton()) { //getSingleton中的第二個參數類型是ObjectFactory<?>,是一個函數式接口,不會馬上執行,而是在 //getSingleton方法中,調用ObjectFactory的getObject,纔會執行createBean sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }
這裏面的createBean方法,再點進去啊,可是又點不進去了,這是接口啊,可是別慌,這個接口又只有一個實現類,因此說 沒事,就是幹,這個實現類爲org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory。
這個實現的方法裏面又作了不少事情,咱們就不去看了,我就是帶着你們找到那幾個生命週期的回調到底定義在哪裏就OK了。
Object beanInstance = doCreateBean(beanName, mbdToUse, args);//建立bean,核心 if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance;
再繼續深刻doCreateBean方法,這個方法又作了一堆一堆的事情,可是值得開心的事情就是 咱們已經找到了咱們要尋找的東西了。
首先是建立實例,位於:
instanceWrapper = createBeanInstance(beanName, mbd, args);//建立bean的實例。核心
其次是填充屬性,位於:
populateBean(beanName, mbd, instanceWrapper);//填充屬性,炒雞重要
在填充屬性下面有一行代碼:
exposedObject = initializeBean(beanName, exposedObject, mbd);
繼續深刻進去。
aware系列接口的回調位於initializeBean中的invokeAwareMethods方法:
invokeAwareMethods(beanName, bean);
private void invokeAwareMethods(final String beanName, final Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ClassLoader bcl = getBeanClassLoader(); if (bcl != null) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } }
BeanPostProcessor的postProcessBeforeInitialization方法位於initializeBean的
if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); }
@Override public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
afterPropertiesSet init-method位於initializeBean中的
invokeInitMethods(beanName, wrappedBean, mbd);
這裏面調用了兩個方法,一個是afterPropertiesSet方法,一個是init-method方法:
((InitializingBean) bean).afterPropertiesSet();
invokeCustomInitMethod(beanName, bean, mbd);
BeanPostProcessor的postProcessAfterInitialization方法位於initializeBean的
if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); }
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
固然在實際的開發中,應該沒人會去銷燬Spring的應用上下文把,因此剩餘的兩個銷燬的回調就不去找了。
這就是廣爲流傳的Spring Bean的生命週期,我也帶着你們找到了各類回調和鉤子,可是我認爲這並不是是Spring Bean完整的生命週期,只是通過簡化的,那麼我認爲的完整的生命週期是如何的呢,請聽下回分解。
原文出處:https://www.cnblogs.com/CodeBear/p/10867707.html