入口:AbstractApplicationContext類refresh方法264行:
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();java
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { // 真正刷新BeanFactory的方法 this.refreshBeanFactory(); // 返回BeanFactory return this.getBeanFactory(); }
//真正調用的是AbstractRefreshableApplicationContext的refreshBeanFactory方法 protected final void refreshBeanFactory() throws BeansException { //判斷是否已經存在BeanFactory,若是存在就銷燬and關閉 if(this.hasBeanFactory()) { this.destroyBeans(); this.closeBeanFactory(); } try { // 真正建立BeanFactory的方法 DefaultListableBeanFactory beanFactory = this.createBeanFactory(); // 給BeanFactory設置一個id,怎麼設置的本身看~ beanFactory.setSerializationId(this.getId()); // 定製BeanFactory this.customizeBeanFactory(beanFactory); // 加載Bean的Definition解析器 this.loadBeanDefinitions(beanFactory); // 下面就是將建立出來的BeanFactory保存起來 Object var2 = this.beanFactoryMonitor; synchronized(this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException var5) { throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5); } }
//AbstractRefreshableApplicationContext第103行 protected DefaultListableBeanFactory createBeanFactory() { //建立並返回一個DefaultListableBeanFactory工廠,其中參數是他的父工廠 return new DefaultListableBeanFactory(this.getInternalParentBeanFactory()); } //AbstractApplicationContext第725行,這裏注意AbstractApplicationContext是AbstractRefreshableApplicationContext的父類,而這段邏輯對於全部上下文都管用,因此卸載這(後面這句話是我瞎猜的~) protected BeanFactory getInternalParentBeanFactory() { // 判斷當前上下文是否有父上下文,若是有就返回回去。固然這裏是沒有的,在Spring-MVC裏面的話就會有了~這樣看來工廠之間也有鏈路關係額。之前都不知道 return (BeanFactory)(this.getParent() instanceof ConfigurableApplicationContext?((ConfigurableApplicationContext)this.getParent()).getBeanFactory():this.getParent()); }
//AbstractRefreshableApplicationContext第725行 protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { //若是 容許bean定義重寫 有值,則設置對於的值,這裏默認沒有,不過你要是使用事務的話,就會有了。 if(this.allowBeanDefinitionOverriding != null) { beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding.booleanValue()); } //若是 容許循環引用 有值,則設置對於的值,這裏默認也沒有。 if(this.allowCircularReferences != null) { beanFactory.setAllowCircularReferences(this.allowCircularReferences.booleanValue()); } }
//這裏實際調用的是AbstractXmlApplicationContext的方法,若是你是Annotation版的,那麼走的就是Annotation版的了,到時候再說- - protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { //建立一個XmlBeanDefinition的解析器 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); // 設置系統屬性 beanDefinitionReader.setEnvironment(this.getEnvironment()); // 設置資源加載器 beanDefinitionReader.setResourceLoader(this); // 設置實體解析器 beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); // 初始化BeanDefinitionReader解析器 this.initBeanDefinitionReader(beanDefinitionReader); // 加載BeanDefinitions // 大內容,單獨分析 this.loadBeanDefinitions(beanDefinitionReader); }
//真正調用的是AbstractRefreshableApplicationContext的getBeanFactory方法 //就是將上一步建立的BeanFactory返回回去。 public final ConfigurableListableBeanFactory getBeanFactory() { Object var1 = this.beanFactoryMonitor; synchronized(this.beanFactoryMonitor) { if(this.beanFactory == null) { throw new IllegalStateException("BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext"); } else { return this.beanFactory; } } }
截至到如今,除了加載BeanDefinitions沒有講之外(實際上是我本身也還沒開始看....),BeanFactory的建立過程已經徹底結束。 首先spring會設置一堆亂七八糟的東西,而後定位在XML文件的位置,而且保存起來。這就是整個流程的第一步,資源定位。立刻咱們就要開始第二步,資源的加載了~下期見~spring